Utiliser des tests dans vos projets
Dernière mise à jour le
Les tests sont largement utilisés en programmation pour s’assurer que les classes, fonctions et méthodes se comportent comme prévu. Quand le code est mis à jour, les tests garantissent aussi que les changements n’ont pas touché tout le travail effectué auparavant.
Mais les tests peuvent aussi être très utiles dans les projets d’analyse de données et de visualisation. Vous pouvez les utiliser pour vous assurer que vos calculs correspondent à une référence indépendante. Ou, une fois que vous avez des résultats, pour vérifier que vos modifications n’ont pas un impact inattendu sur vos conclusions ou vos visuels.
Personnellement, j’utilise les tests pour renforcer ma confiance dans mon travail. Je peux vérifier quelque chose une fois et écrire un test pour le valider. Par la suite, je saurai avec certitude que ce résultat est garanti. Et si le test échoue, cela signifie qu’un problème sérieux s’est produit et nécessite mon attention !
Dans cette leçon, nous allons coder une fonction simple pour calculer des pourcentages et créer des tests pour nous assurer qu’elle fonctionne comme prévu.
Configuration
Créez un nouveau dossier vide, ouvrez-le dans VS Code et créez-y un fichier nommé main.ts. Ajoutez cette ligne et enregistrez le fichier.
console.log("Hello!");
Nous utiliserons l’outil de test intégré à Node. Une fois notre premier test écrit, nous le lancerons avec node --test.
Écrire la fonction à tester
Créez un dossier helpers et placez-y le fichier getPercentage.ts avec ce code. C’est la fonction que nous voulons tester. Elle s’attend à recevoir deux nombres et retourne le pourcentage sous forme de texte.
export default function getPercentage(
current: number,
total: number,
): string {
const percentage = (current / total) * 100;
return `${percentage}%`;
}Mettez maintenant à jour main.ts pour utiliser la fonction.
import getPercentage from "./helpers/getPercentage.ts";
console.log(getPercentage(50, 100));Enregistrez le fichier et exécutez la commande ci-dessous dans le terminal de VS Code.
node main.tsTout fonctionne comme prévu ! La fonction retourne 50%.

Créer des tests
Est-ce que notre fonction fonctionne vraiment comme prévu ? Vérifions !
Créer un test, c’est simple. Nous avons besoin de deux choses.
test, du modulenode:test, nous permet de nommer un test et d’indiquer à Node quel code exécuter.assert, du modulenode:assert/strict, nous permet de vérifier le résultat. Nous utiliseronsassert.strictEqualpour comparer le résultat du code que nous testons à la valeur attendue.
Ces deux modules sont intégrés à Node, donc vous n’avez rien d’autre à installer.
Créons maintenant le fichier de test. J’aime organiser mes tests selon la même structure que le reste du code. Créez un dossier tests à la racine du projet, ajoutez-y un dossier helpers, puis créez le fichier getPercentage.test.ts dans ce dossier. Le suffixe .test.ts aide Node à trouver le fichier lorsque vous lancez les tests.
Ajoutez le code suivant dans tests/helpers/getPercentage.test.ts.
import assert from "node:assert/strict";
import { test } from "node:test";
import getPercentage from "../../helpers/getPercentage.ts";
test("should return 50% for 50 out of 100", () => {
const result = getPercentage(50, 100);
assert.strictEqual(result, "50%");
});Voici ce que fait ce code.
- La ligne 5 crée un nouveau test avec une description. Vous pouvez écrire ce que vous voulez. Gardez la description simple et claire.
- Les lignes 6 et 7 contiennent le code exécuté par le test. La ligne 6 appelle
getPercentage(50, 100)et stocke la valeur retournée dansresult. La ligne 7 utiliseassert.strictEqualpour comparerresultau texte attendu,"50%".
Si result contient exactement le texte "50%", le test réussit. Sinon, il échoue.
Exécuter les tests
Ouvrez le terminal dans VS Code et lancez la commande ci-dessous. Node cherche les fichiers de test qui se terminent par .test.ts ou .test.js dans votre projet, y compris dans les sous-dossiers, et les exécute.
node --testVous devriez voir une coche à côté du nom de votre test pour indiquer qu’il a réussi.

Vous verrez peut-être des erreurs de type aux lignes 1 et 2 dans VS Code. Vous pouvez les ignorer pour cette leçon. Les deux modules sont intégrés à Node et le test s’exécutera quand même.
Ajouter des tests
Selon votre contexte, le test que nous venons d’écrire peut être suffisant. Par exemple, peut-être que vous vouliez simplement vérifier le résultat d’une étape dans votre analyse de données et que vous voulez que cela reste comme ça à l’avenir.
Ajoutons deux autres tests.
- Le premier vérifie que
getPercentage(1, 3)retourne"33.33%", avec deux décimales. - Le second vérifie que
getPercentage(1, 0)déclenche une erreur, puisque la division par zéro est indéfinie. Nous utilisonsassert.throwspour vérifier le messageTotal must not be zero.
Écrivons les deux tests avec la version actuelle de getPercentage. Modifiez le fichier de test avec le code ci-dessous.
import assert from "node:assert/strict";
import { test } from "node:test";
import getPercentage from "../../helpers/getPercentage.ts";
test("should return 50% for 50 out of 100", () => {
const result = getPercentage(50, 100);
assert.strictEqual(result, "50%");
});
test("should round 1 out of 3 to two decimal places", () => {
const result = getPercentage(1, 3);
assert.strictEqual(result, "33.33%");
});
test("should throw an error when the total is zero", () => {
assert.throws(() => getPercentage(1, 0), { message: "Total must not be zero." });
});Enregistrez le fichier de test et relancez les tests.
node --testVous verrez que les deux nouveaux tests échouent. Le premier réussit toujours.

Faites défiler le terminal vers le bas pour voir pourquoi chaque test a échoué. Le test d’arrondi attendait "33.33%", mais getPercentage(1, 3) a retourné "33.33333333333333%" avec beaucoup plus de décimales.
test at tests/helpers/getPercentage.test.ts:10:1
✖ should round 1 out of 3 to two decimal places (0.44575ms)
AssertionError [ERR_ASSERTION]: Expected values to be strictly equal:
actual expected
'33.33333333333333%'
at TestContext.<anonymous> (file:///Users/nael/Desktop/test/tests/helpers/getPercentage.test.ts:12:12)
at Test.runInAsyncScope (node:async_hooks:227:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async startSubtestAfterBootstrap (node:internal/test_runner/harness:387:3) {
generatedMessage: true,
code: 'ERR_ASSERTION',
actual: '33.33333333333333%',
expected: '33.33%',
operator: 'strictEqual',
diff: 'simple'
}Pour le test de division par zéro, le message Missing expected exception indique que getPercentage(1, 0) s’est exécuté sans déclencher d’erreur.
test at tests/helpers/getPercentage.test.ts:15:1
✖ should throw an error when the total is zero (0.097542ms)
AssertionError [ERR_ASSERTION]: Missing expected exception.
at TestContext.<anonymous> (file:///Users/nael/Desktop/test/tests/helpers/getPercentage.test.ts:16:12)
at Test.runInAsyncScope (node:async_hooks:227:14)
at Test.run (node:internal/test_runner/test:1402:25)
at Test.processPendingSubtests (node:internal/test_runner/test:974:18)
at Test.postRun (node:internal/test_runner/test:1542:19)
at Test.run (node:internal/test_runner/test:1467:12)
at async Test.processPendingSubtests (node:internal/test_runner/test:974:7) {
generatedMessage: false,
code: 'ERR_ASSERTION',
actual: undefined,
expected: { message: 'Total must not be zero.' },
operator: 'throws',
diff: 'simple'
}Corrigeons getPercentage pour que tous nos tests réussissent. 👷
Ajouter l’arrondi
Commençons par l’arrondi. Modifiez helpers/getPercentage.ts comme ci-dessous pour ajouter un paramètre facultatif nommé decimals. Si vous l’omettez, la fonction se comporte comme avant. Si vous passez un nombre, toFixed arrondit le pourcentage au nombre de décimales indiqué.
export default function getPercentage(
current: number,
total: number,
decimals?: number,
): string {
const percentage = (current / total) * 100;
const formatted = decimals === undefined
? percentage.toString()
: percentage.toFixed(decimals);
return `${formatted}%`;
}Dans le test d’arrondi, ajoutez 2 comme troisième argument de getPercentage pour demander deux décimales. La ligne modifiée est surlignée ci-dessous.
import assert from "node:assert/strict";
import { test } from "node:test";
import getPercentage from "../../helpers/getPercentage.ts";
test("should return 50% for 50 out of 100", () => {
const result = getPercentage(50, 100);
assert.strictEqual(result, "50%");
});
test("should round 1 out of 3 to two decimal places", () => {
const result = getPercentage(1, 3, 2);
assert.strictEqual(result, "33.33%");
});
test("should throw an error when the total is zero", () => {
assert.throws(() => getPercentage(1, 0), { message: "Total must not be zero." });
});Enregistrez les deux fichiers et relancez les tests avec la commande ci-dessous.
node --testLe premier test réussit toujours sans l’argument decimals. Le deuxième réussit maintenant aussi, donc notre modification pour l’arrondi a fonctionné ! 🎉
Le troisième test échoue encore. C’est normal, puisque nous n’avons pas encore géré la division par zéro.

Gérer la division par zéro
Pour gérer la division par zéro, ajoutez une vérification avant de diviser. Utilisez une condition if pour vérifier si total vaut zéro. Si c’est le cas, déclenchez tout de suite une erreur avec le message attendu par le test.
Modifiez getPercentage comme ci-dessous et enregistrez le fichier.
export default function getPercentage(
current: number,
total: number,
decimals?: number,
): string {
if (total === 0) {
throw new Error("Total must not be zero.");
}
const percentage = (current / total) * 100;
const formatted = decimals === undefined
? percentage.toString()
: percentage.toFixed(decimals);
return `${formatted}%`;
}Relancez les tests avec cette commande.
node --testTous nos tests réussissent maintenant ! 🎉

Exécuter et surveiller les tests
Vous n’avez pas besoin d’exécuter tous vos tests chaque fois que vous modifiez votre code. Pour exécuter un fichier de tests précis, indiquez son chemin à Node.
node --test tests/helpers/getPercentage.test.tsPour exécuter un test précis, donnez sa description à --test-name-pattern.
node --test --test-name-pattern="should round 1 out of 3 to two decimal places"Comme avec node --watch main.ts, vous pouvez surveiller vos tests avec la commande ci-dessous. Node relance automatiquement les tests concernés quand vous enregistrez une modification dans un fichier de test ou dans l’une de ses dépendances.
node --test --watchTests automatisés
Vous pouvez bien sûr toujours lancer les tests localement. Vous pouvez même définir une commande npm pour les exécuter plus facilement.
Mais si vous utilisez GitHub, vous pouvez configurer des tests automatisés dans vos projets. C’est une configuration courante pour les librairies en code ouvert, mais vous pouvez l’utiliser pour n’importe quel projet.
Par exemple, j’ai des centaines de tests pour la librairie Simple Data Analysis. Vous pouvez les explorer ici .
J’utilise GitHub Actions pour exécuter ces tests automatiquement avant de publier une nouvelle version de la librairie. La configuration est simple. Un petit fichier indique à GitHub d’exécuter les tests dans le nuage.
Tester des pages web et des visualisations
Dans cette leçon, nous avons exécuté des tests simples en local pour vérifier que notre fonction renvoyait les valeurs attendues.
Vous pouvez aussi tester quelque chose de plus complexe, comme une page web. Est-ce que la page affiche le bon résultat quand vous cliquez sur un bouton ou sélectionnez une option ? Une librairie comme Playwright peut exécuter ces tests dans un navigateur et vérifier ce qui s’affiche.
Vous pouvez aussi tester les graphiques que vous exportez avec Simple Data Analysis . Disons que votre script enregistre un graphique au format SVG. En poursuivant votre analyse, vous pouvez comparer le texte du nouveau SVG à celui d’une version que vous avez conservée pour repérer les changements inattendus dans le graphique, y compris dans les données qu’il affiche.
Si votre script enregistre le graphique au format PNG, vous pouvez le comparer octet par octet à un fichier de référence ou utiliser une librairie de traitement d’images pour comparer les pixels.
Rappelez-vous que presque tout peut être testé !
Conclusion
Vous n’avez pas toujours besoin de tests, mais dès que vous travaillez sur un projet à long terme ou complexe, prendre le temps d’écrire de simples tests à chaque fois que vous créez une nouvelle méthode ou fonction peut s’avérer être un excellent investissement.
Vous aurez plus confiance en votre code et, entre le typage et les tests, vous éviterez beaucoup de vilains bugs et erreurs ! 🐞
Et si jamais vous avez un bug à corriger, ajouter un test pour le couvrir garantira qu’il ne reviendra jamais !
Bonnes séances de test ! 👷