Vitest : Assertions
Les assertions permettent de garantir le bon fonctionnement d'un extrait de code. Découvrons leur rôle et leur syntaxe.
Qu’est-ce qu’une assertion ?
Rôle
Dans l’écosystème des frameworks de test, le terme d’« assertion » fait référence à une déclaration qui vérifie qu’une condition spécifique est vraie pendant l’exécution d’un test unitaire.
Elle permet de garantir que le comportement du code correspond aux attentes définies par le développeur.
Si je possède une fonction utilitaire calculant la somme de 2 nombres, alors une assertion consisterait par exemple à écrire une condition qui vérifie que notre fonction :
- « Retourne bien
4
pour la somme1 + 3
» - « Retourne bien
null
s’il manque un argument » - « Retourne bien
null
si les arguments ne sont pas des nombres » - Etc.
APIs compatibles : Chai et Jest
Pour écrire des assertions, Vitest intègre les APIs (comprendre ici « les méthodes ») d’assertions de la librairie Chai ou encore du framework de test Jest.
Ces API offrent aux développeurs des approches différentes pour vérifier des conditions.
Vitest offre deux méthodes pour écrire des assertions : expect()
et assert()
. Bien qu’elles aient toutes deux pour but d’effectuer des assertions, elles adoptent une approche syntaxique distincte.
Ecrire des assertions
Expect
Fonctionnement
Cette approche consiste à écrire ses assertions avec la méthode expect()
.
Cette fonction va prendre en argument l’élément à tester (fonction, objet…) puis permettre d’y expliciter le résultat attendu en chaînant des méthodes de vérification.
Import
Importons la méthode expect()
.
import { expect } from 'vitest'
Utilisation
Avec l’API de Chai
L’API de Chai confère une méthodologie de développement dirigée par le comportement nommée BDD (Behavior-Driven Development).
Cette méthodologie consiste à chaîner des assertions syntaxiquement proches du langage naturel, afin de rendre les tests plus lisibles et expressifs.
Une assertion se présente sous la forme de :
- Mots-clés de liaison (
to
,be
,is
,that
,which
,and
…) - Méthodes et mots-clés de vérification (
equal()
,empty()
,true
…)
import { describe, test, expect } from 'vitest'
import { sum, getPseudos } from "../src/utils/demo"
describe("Fonction sum()", () => {
test("Calcul de somme", () => {
expect(sum(1, 3)).to.equal(4)
})
test("Pas d'arguments", () => {
expect(sum()).to.be.null
})
})
describe("Fonction getPseudos()", () => {
test("Récupère 7 pseudos random", () => {
expect(getPseudos(7)).to.be.an('array').that.have.lengthOf(7)
})
test("Pas d'arguments", () => {
expect(getPseudos()).to.be.an('array').that.is.empty
})
})
to.be.an('array').that.is.not.empty
… Difficile de faire plus clair !
Avec l’API de Jest
L’API de Jest offre une syntaxe plus compacte, limitant le chaînage d’assertions, car elle :
- Offre des méthodes de vérification plus spécifiques (aussi appelées « matchers »). Par exemple
.to.be.below()
de l’API de Chai se verra remplacé par.toBeLessThan()
avec l’API de Jest. - N’intègre aucun mot-clé de liaison. Seul le mot-clé
not
permet d’inverser un test (on parle de « modifier »).
import { describe, test, expect } from 'vitest'
import { sum, getPseudos } from "../src/utils/demo"
describe("Fonction sum()", () => {
test("Calcul de somme", () => {
expect(sum(1, 3)).toBe(4)
})
test("Pas d'arguments", () => {
expect(sum()).toBeNull()
})
})
describe("Fonction getPseudos()", () => {
test("Récupère 7 pseudos random", () => {
expect(getPseudos(7)).toBeInstanceOf(Array).toHaveLength(7)
})
test("Pas d'arguments", () => {
expect(getPseudos()).toBeInstanceOf(Array).toHaveLength(0)
})
})
Consulter la documentation officielle de expect()
.
Assert
Fonctionnement
Cette seconde approche consiste à écrire ses assertions avec la méthode assert()
.
Cette méthode est plus flexible qu’expect()
puisqu’elle permet :
- D’évaluer directement une expression de manière « traditionnelle » avec les opérateurs logiques et de comparaison.
OU
- D’utiliser des méthodes de vérification (
.equal()
,.isTrue()
,.isNull()
…)
Import
Importons la méthode assert()
.
import { assert } from 'vitest'
Utilisation
Approche traditionnelle
Utilisons assert()
pour évaluer nos expressions de manière traditionnelle.
import { describe, test, expect } from 'vitest'
import { sum, getPseudos } from "../src/utils/demo"
describe("Fonction sum()", () => {
test("Calcul de somme", () => {
assert(sum(1, 3) === 4)
})
test("Pas d'arguments", () => {
assert(sum() === null)
})
})
describe("Fonction getPseudos()", () => {
test("Récupère 7 pseudos random", () => {
assert(getPseudos(7) instanceof Array && getPseudos(7).length === 7)
})
test("Pas d'arguments", () => {
assert(getPseudos() instanceof Array && getPseudos().length === 0)
})
})
Approche par méthode spécifique
Utilisons assert()
pour évaluer nos expressions avec les méthodes de vérification proposées par Vitest.
import { describe, test, expect } from 'vitest'
import { sum, getPseudos } from "../src/utils/demo"
describe("Fonction sum()", () => {
test("Calcul de somme", () => {
assert.equal(sum(1, 3), 4)
})
test("Pas d'arguments", () => {
assert.isNull(sum())
})
})
describe("Fonction getPseudos()", () => {
test("Récupère 7 pseudos random", () => {
assert.isArray(getPseudos(7))
assert.lengthOf(getPseudos(7), 7)
})
test("Pas d'arguments", () => {
assert.isArray(getPseudos())
assert.isEmpty(getPseudos())
})
})
Vous remarquez ici qu’il est possible de spécifier plusieurs assert
au sein d’un seul test. Cela signifie que toutes les assertions doivent être vraies pour que le test soit passé avec succès.
Consulter la documentation officielle de assert()
.
Expect VS Assert
Opposons dans un tableau comparatif ces deux approches :
Critère | expect() | assert() |
---|---|---|
Chaînage | Oui | Non |
Syntaxe | Syntaxe expressive | Syntaxe traditionnelle |
Lisibilité | Fluide et lisible | Explicite mais peut être verbeuse |
Usage | Préféré par ceux appréciant la syntaxe expressive ou venant de contextes utilisant Jest ou Chai | Préféré par ceux habitués aux frameworks traditionnels |
Exemples | expect(foo).to.be.a('string') (Chai) ou expect(foo).toBeTypeOf('string') (Jest) | assert.typeOf(foo, 'string') ou assert.typeOf(foo, 'string') |
Gestion des erreurs
Les méthodes expect()
et assert()
prennent en charge les messages d’erreur personnalisés.
Si une assertion échoue, alors un message d’erreur accompagnera le résultat du test dans le terminal.
Avec expect()
:
// Chai API
expect(foo, "foo devrait être vrai").to.be.true;
// Jest API
expect(foo, "foo devrait être vrai").toBe(true);
Avec assert()
:
// Approche traditionnelle
assert(foo === true, "foo devrait être vrai");
// Approche par méthode spécifique
assert.isTrue(foo, "foo devrait être vrai");