Découvrez Jest, l’un des frameworks de test les plus utilisés en JavaScript
Si vous vous souvenez bien, au début de ce cours, vous avez utilisé la commande npm install
. Cette commande vous a permis d’installer les librairies requises pour ce projet, et Jest en faisait partie .
Mais alors Jest, c’est quoi ?
Jest est un framework de test JavaScript. Il est utilisé pour des projets TypeScript, NodeJS, React, Angular, Vue, et même le nôtre. C’est plutôt une bonne nouvelle, parce que vous allez pouvoir réutiliser Jest dans tous vos projets avec un minimum d'adaptation !
Jest se focalise vraiment sur la simplicité et la facilité : l’idée est de pouvoir écrire des tests facilement et rapidement, sans trop se prendre la tête sur la configuration, et de pouvoir les exécuter dans différents environnements (développement, préproduction, etc.).
Découvrez comment Jest est configuré
Notre projet fil rouge n’utilisant aucun framework (React, Angular, Vue, etc.), j’ai dû faire un peu de configuration pour que tout fonctionne normalement.
Mais attends, ça veut dire que je vais devoir faire ça moi aussi en entreprise ?
En théorie, non. Le plus souvent, le fait d’installer et de paramétrer les tests, autrement dit de les rendre prêts à l’emploi, est souvent réalisé par le lead développeur, ou par un développeur senior. Cela dit, il est toujours intéressant de comprendre un peu comment ça marche. :)
Vous pouvez rester sur la branche main
ici. Je vous invite à regarder avec attention :
Le fichier package.json ;
Le dossier node_modules ;
babel.config.cjs.
La configuration de Jest “tient” dans ces trois éléments. :) Une fois que vous pensez avoir une idée, regardez la vidéo ci-dessous : je vous détaille les fichiers créés, les commandes que j’ai utilisées, et où est situé Jest.
Découvrez les commandes liées à Jest
Dernier point avant de s’attaquer à la documentation de Jest : les commandes liées à Jest.
Dans la vidéo précédente, je vous ai montré que Jest était installé dans le répertoire node_modules
. Ce répertoire contient toutes les librairies (on dit aussi dépendances) pour que ce projet fonctionne.
Voici quelques commandes de Jest à connaître :
node_modules/.bin/jest --help
– vous permet d’afficher la documentation de Jest et les options possibles.node_modules/.bin/jest --watch
– vous permet de “watcher” vos fichiers. Autrement dit, les tests se relancent sur les fichiers modifiés. Un peu comme avec Sass. :)
Prenez en main Jest
Prise en main de l’écriture des tests avec Jest
Pour réaliser des tests avec Jest, vous aurez besoin de suivre quelques conventions.
La première concerne le nommage du fichier. Pour que Jest reconnaisse vos fichiers comme des fichiers de tests, vous devez ajouter .test
au moment de la création de votre fichier. Par exemple, pour la fonction getNumberOfPages
, j’ai appelé mon fichier index.unit.test.js
.
Sur le code du projet, je vois un autre fichier qui s’appelle index.integration.test.js
, c’est quoi ?
Décidément, vous avez l'œil !
En fait, il s’agit de mon test d’intégration que nous verrons dans la prochaine partie. J’ai séparé mes tests unitaires de mes tests d’intégration :
D’une part, pour vous montrer que c’est possible de le faire. :) Comme je vous l’ai dit plus haut, tant que votre fichier comprend le mot « test », Jest va le parcourir ;
D’autre part, parce que ça augmente la lisibilité de mon code. On sait directement où sont les tests unitaires et d’intégration.
Si on revient à notre code de test de tout à l’heure, voici ce que nous avions :
import Pagination from "./index"
/**
* @function Pagination.getNumberOfPages
*/
describe('Pagination Unit Test Suites', () => {
it('should return something', () => (
expect(Pagination.getNumberOfPages(12)).toBeDefined()
))
it('should return 0', () => (
expect(Pagination.getNumberOfPages(0)).toEqual(0)
))
it('should return 1', () => (
expect(Pagination.getNumberOfPages(7)).toEqual(1)
))
it('should return 5', () => (
expect(Pagination.getNumberOfPages(34)).toEqual(5)
))
})
Décomposons ensemble ce bloc de code :
Dans un premier temps, j’importe le code du fichier
js/common/pagination/index.js
.describe
vous permet de créer un bloc de tests (ou “Test Suite”, en anglais). Ce n’est pas un élément obligatoire, mais cela permet de renseigner le type de test que vous réalisez.it
contient le message indiquant le résultat attendu. On écrit souvent les tests sous la forme : it(‘should ...’). Par exemple,it(‘should return something’)
ou en français, “ça devrait retourner quelque chose”. Il est important ici de faire un message le plus synthétique et complet possible.expect()
va vous permettre d'exécuter la fonction et de stocker la valeur de retour de cette dernière.toBeDefined()
outoEqual()
est le test en lui-même. C’est ce qu’on appelle le “matcher” côté test. Autrement dit, Jest va tester si le résultat deexpect()
correspond au “matcher”.
Et voilà ! Nous avons l’ossature complète de notre test. Pas mal, non ?
Découvrez les matchers de Jest
Bon, maintenant que vous connaissez les éléments qui composent un test, il est temps de nous intéresser à l’un des aspects les plus essentiels : les matchers (pour comparateurs, en français).
Dans la vidéo ci-dessous, je vais vous présenter les principaux matchers de Jest ; vous pourrez être sur la branche main
. Ces exemples sont contenus dans le dossier js/samples/unit
.
Configurez l’exécution de vos tests
Quand on écrit des tests, il arrive parfois qu’on veuille réaliser des opérations avant chaque test et après chaque test.
Par exemple, admettons que nous souhaitions réaliser un appel API pour récupérer nos données météo avant le début de chaque test.
Nous pourrions tout à fait écrire ce bout de code dans chacun des tests. Autrement dit, dans chaque it
, nous aurions le bout de code pour récupérer nos données météo, puis le test en lui-même.
Cela dit, cela va faire pas mal de répétitions dans le code, et surtout ça va nuire un peu à la lisibilité de ce dernier. Jest nous fournit des fonctions pour gérer ces cas élégamment :
beforeEach
va exécuter ce bloc de code avant chaque test.afterEach
va exécuter ce bloc de code après chaque test.beforeAll
va exécuter ce bloc de code au début de la phase de test, et non avant chaque test.afterAll
va exécuter ce bloc de code à la fin de la phase de test.
Mais du coup, ça s’écrit comment ?
Regardez le code ci-dessous, ça va vous aider à y voir plus clair.
let $wrapper
beforeEach(() => {
$wrapper = document.createElement('div')
})
afterEach(() => {
$wrapper = null
})
/**
* @function Pagination.render
*/
describe('Pagination Integration Test Suites', () => {
it('should render 0 pagination list item', () => {})
it('should render 2 pagination list item', () => {})
it('should render 3 pagination list item', () => {})
})
L’exemple ci-dessus nous montre le test d’intégration de notre système de pagination.
Ici, beforeEach
me permet d'initialiser une div
au début de chaque test, et afterEach
me permet de la supprimer à la fin. Cette div
est stockée dans la variable $wrapper
.
Écrivez vos premiers tests unitaires
Maintenant que vous connaissez un peu mieux comment réaliser des tests, vous allez pouvoir réaliser vos premiers tests unitaires. Pour cet exercice, vous aurez besoin de vous mettre sur la branche partie-2/chapitre-2-c
.
Dans la première issue, vous allez tester la fonction
isInTestEnv
.Dans la deuxième issue, vous allez tester la fonction
retrieveSensorsData
.
J’ai déjà créé les deux fichiers de test, vous n’avez plus qu’à les coder. :)
Essayez de réaliser les tests de votre code avant de regarder la solution ci-dessous.
Vous pouvez trouver la solution sur la branche partie-2/chapitre-2-c-solution
.
En résumé
Jest est LE framework de test JavaScript : il permet de facilement créer des tests unitaires avec une configuration proche de zéro. :)
Vos tests doivent être dans un fichier comportant le mot
test
. La bonne pratique consiste à les nommernomDeMonFichierTesté.test.js
.Un test doit comporter
it
(qui correspond au point d’entrée du test), etexpect
, ainsi que la valeur de retour testée.
Vous savez maintenant comment rédiger des tests unitaires, félicitations ! C’est une étape majeure dans votre vie de développeur ! On va à présent s’intéresser aux tests d’intégration dans la prochaine partie !