Vous corrigez un calcul de TVA, tout semble fonctionner… et trois semaines plus tard, quelqu’un découvre que les remises ne s’appliquent plus. Un test automatisé est un petit programme qui exécute votre code et vérifie qu’il produit le résultat attendu. Lancé à chaque modification, il détecte ces régressions en quelques secondes.
Les tests apportent aussi :
- de la confiance pour refactoriser : on peut réorganiser le code sans peur ;
- une documentation vivante : les tests montrent comment utiliser une fonction ;
- un meilleur design : un code difficile à tester est souvent trop couplé.
La pyramide des tests
| Niveau | Ce qu’on teste | Vitesse | Quantité |
|---|---|---|---|
| Unitaire | Une fonction ou un module isolé | Millisecondes | Beaucoup |
| Intégration | Plusieurs modules ensemble (route + base) | Secondes | Moyenne |
| Bout en bout (E2E) | L’application entière via le navigateur | Lent | Peu |
On commence par la base : les tests unitaires.
Les assertions avec node:assert
Node.js fournit le module node:assert. Une assertion vérifie une condition et lève une AssertionError si elle est fausse.
const assert = require("node:assert");
function prixTTC(ht, taux = 0.2) {
if (ht < 0) throw new RangeError("Prix négatif");
return Math.round(ht * (1 + taux) * 100) / 100;
}
// Valeurs simples : comparaison stricte (===)
assert.strictEqual(prixTTC(10), 12);
assert.strictEqual(prixTTC(10, 0.055), 10.55);
// Objets et tableaux : comparaison du contenu
assert.deepStrictEqual([1, 2].map((x) => x * 2), [2, 4]);
// Erreurs : on passe une FONCTION qui sera appelée par assert
assert.throws(() => prixTTC(-1), RangeError);
// Expressions régulières
assert.match("Commande #123", /#\d+/);
Attention à deux pièges :
assert.equal(non strict) utilise==:assert.equal(1, "1")passe. Préférez les variantes strictes, ou importezrequire("node:assert/strict").assert.strictEqual({a: 1}, {a: 1})échoue : deux objets distincts ne sont pas===. UtilisezdeepStrictEqual.
Choisir ses cas de test
Pour chaque fonction, posez-vous ces questions :
- Cas nominal : l’usage normal donne-t-il le bon résultat ?
- Cas limites : zéro, chaîne vide, tableau vide, un seul élément, valeurs maximales, arrondis.
- Entrées invalides : type incorrect, valeur négative,
undefined.
Un message d’erreur clair aide énormément quand un test échoue :
assert.strictEqual(prixTTC(0), 0, "Un prix nul doit rester nul");
À retenir
Un test = préparer des données, appeler le code, vérifier le résultat. Utilisez les assertions strictes, testez les cas limites, et gardez des tests rapides et indépendants.
Exercices
Les solutions et les tests restent sur le serveur. Dans l'espace étudiant, ton code est exécuté et corrigé, et le tuteur donne des indices avant la solution.
Premières assertions
La fonction
moyenne(notes)est fournie. Écrivez la fonctiontesterMoyenne()qui utiliseassertpour vérifier :moyenne([10, 20])vaut15;moyenne([7])vaut7;moyenne([])lève uneRangeError.
Appelez ensuite
testerMoyenne()en fin de fichier.function moyenne(notes) { if (notes.length === 0) throw new RangeError("Liste vide"); return notes.reduce((a, b) => a + b, 0) / notes.length; } function testerMoyenne() { // Vos assertions ici } testerMoyenne();Un vérificateur qui attrape les bugs
Écrivez
verifierSlugify(slugify)qui reçoit une implémentation deslugifyet lève uneAssertionErrorsi elle est incorrecte. Une implémentation correcte doit :- transformer
"Bonjour le Monde"en"bonjour-le-monde"; - retirer les espaces en début/fin :
" Café "donne"cafe"(accents retirés) ; - renvoyer
""pour une chaîne vide.
Le validateur passera de bonnes et de mauvaises implémentations à votre fonction.
function verifierSlugify(slugify) { // Vos assertions sur slugify(...) }- transformer
Choisir la bonne assertion
Quelle assertion vérifie que
getUser()renvoie l’objet{ id: 1, nom: "Ada" }?- assert.strictEqual(getUser(), { id: 1, nom: "Ada" })
- assert.deepStrictEqual(getUser(), { id: 1, nom: "Ada" })
- assert.ok(getUser() == { id: 1, nom: "Ada" })
Quiz de fin de leçon
Quel niveau de test doit être le plus nombreux ?
- Les tests de bout en bout
- Les tests unitaires
- Les tests manuels
Que fait
assert.equal(1, "1")du module node:assert classique ?- Il échoue
- Il passe, car il utilise ==
- Il lève une TypeError
Lequel est un cas limite pour une fonction de moyenne ?
- [10, 20]
- Un tableau vide
- [12, 14, 16]
La suite du cours
- Le test runner de Node : organiser ses tests15 min
- Tests asynchrones et doublures (mocks, stubs, espions)18 min
- TDD et frameworks de test : Jest et Vitest18 min
- Tests d'intégration, couverture et intégration continue18 min