Tests unitaires avec nodeunit

Commencer un projet en optant pour le TDD (Tests Driven Development, soit en bon français, développement dirigé par les tests) est une excellente idée pour garder un projet stable et maintenable tout au long de sa vie. Ce n'est malheureusement pas toujours évident quand les délais sont trop court ou qu'on n'a pas l'habitude de travailler de la sorte. Mais je vous conseille tous de vous forcer à vous y mettre, le temps perdu à mettre en place ces tests sera trois fois le même temps gagné lors du debug.

Du coup, ici, nous allons parler des tests unitaires coté server dans un projet Node.js. Il existe un nombre incalculable de modules permettant d'arriver à ces fins, mais j'ai personnellement opté pour nodeunit qui m'a semblé le plus clair et le plus simple à mettre en place. Nous allons donc voir comment fonctionnent ces tests unitaires et comment les lancer. Vous pourrez ensuite consulter mon précédent article pour voir comment les lancer automatiquement avec grunt.

npm install

Première chose à faire : installer le module dans votre projet que vous avez correctement initialisé. Usons donc de npm install afin de sauvegarder la dépendance pour le dev :

npm install nodeunit --save-dev

Pour lancer les tests, vous utiliserez la commande nodeunit en lui passant en paramètre le fichier de test ou un dossier contenant des fichiers de test :

nodeunit test.js
nodeunit tests

Vous pouvez aussi utilisez npm ou grunt pour lancer les tests. Nous allons configurer npm.

npm test

Le fichier package.json propose un groupe nommé scripts qui permet de définir une série de scripts nécessaires au cycle de vie du projet. Parmi eux se trouvent la commande test. Nous allons donc indiquer dans notre package.json ce que doit faire npm lorsqu'on lui demande de lancer les tests. À la racine du json, nous allons simplement ajouter les lignes suivantes :

"scripts": {
    "test": "nodeunit tests/*"
  },

Ainsi, lorsque nous taperons npm test, nodeunit sera lancé. L'intérêt de passer par ce raccourci, c'est qu'on peut avoir d'autres traitement à faire avant ou après le lancement de nodeunit, et qu'on pourrait aussi vouloir utiliser un autre outil de tests pour une autre partie du projet : qunit par exemple pour la partie frontale.

Allez ! Il est temps de rédiger un test !

Testons !

Nous allons écrire une classe qui possède une propriété de type Number et une méthode add(n) qui retourne l'addition entre cette propriété et le paramètre passé. Passionnant non ? Nous allons commencer par écrire le test que nous placerons dans un fichier test.js :

Lançons le test :

$ nodeunit test.js 
module.js:333
    throw err;
    ^
Error: Cannot find module './myclass'
    at Function.Module._resolveFilename (module.js:331:15)
    at Function.Module._load (module.js:273:25)
    at Module.require (module.js:357:17)
    at require (module.js:373:17)
    at Object.<anonymous> (/home/hadrien/test/test.js:1:77)
    at Module._compile (module.js:449:26)
    at Object.Module._extensions..js (module.js:467:10)
    at Module.load (module.js:349:32)
    at Function.Module._load (module.js:305:12)
    at Module.require (module.js:357:17)

Oups, il manque le module myclass :x Écrivons le !

On crée un fichier myclass.js et on y met le code de la classe :

var MyClass = function()
{

};

MyClass.prototype = {
    basenumber: 0,
    add: function()
    {

    }
};

module.exports = MyClass;

Et on relance les tests :

$ nodeunit test.js 

**test.js**
✖ testAdd

…

Voilà ! Nous avons un test qui plante ! Il ne reste plus qu'à compléter le code de la classe pour que le test passe, ce qui donnera ceci :

$ nodeunit test.js 

**test.js**
✔ testAdd

**OK: **3 assertions (34ms)

Nous avons écrit notre fonction tout en visualisant tous les cas de figure auxquelles elle se prête, et si un jour, on découvre un bug, il suffira de rajouter un test le reproduisant et de recommencer la séance de codage sans risquer de générer de nouveaux bugs.

Hadrien

Hi, I'm a french Javascript Lead Developer, Web Architect from Toulouse, France. I've worked for 12 years for many projects with YUI, AngularJS, Aurelia.io and now React and React native.

Toulouse, France https://hadrien.eu