Mettre en place Jest pour vos tests unitaires Angular
Par défaut, les applications Angular utilisent Karma et Jasmine pour les tests unitaires. Dans cet article, nous allons voir comment remplacer ces outils par le framework de test Jest.
1. Installer les dépendances
Pour installer les dépendances requises, lancer la commande suivante dans un terminal :
npm install jest jest-preset-angular @types/jest --save-dev
Si vous utilisez Yarn, la commande à lancer est :
yarn add --dev jest jest-preset-angular @types/jest
Jest
Jest est un framework de test complet créé par Facebook et qui est très populaire dans l’écosystème React. Il vient avec tout le bagage nécessaire pour réaliser des tests unitaires pour nos applications JavaScript. Il comprend :
- d’importantes capacités de mock,
- une bibliothèque d’assertion intégrée,
- un outil de code coverage intégré,
- JSDOM, une librairie émulant le navigateur.
JSDOM va nous permettre d’exécuter nos tests unitaires sur nos serveurs d’intégration continue sans configuration supplémentaire.
Je préfère Jest à Karma et Jasmine, car Jest offre une bien meilleure expérience développeur. Il est :
- plus rapide que Karma avec une parallélisation de l’exécution des tests,
- très bien documenté avec une large communauté derrière,
- plus intelligent que Karma (en ne relançant que les tests affectés par exemple),
- un toolkit complet pour les tests unitaires,
- headless par défaut grâce à la librairie JSDOM.
Les déclarations de types pour Jest
Le paquet @types/jest
contient les déclarations de types qui vont permettre à TypeScript d’effectuer la vérification
du typage statique de notre code.
Jest Preset Angular
Le paquet jest-preset-angular
est l’outil qui permet à Jest de comprendre notre code Angular.
C’est ce qui rend possible l’exécution des tests unitaires de notre application Angular via Jest. Il inclut :
ts-jest
, une librairie qui permet à Jest de transpiler à la volée notre code TypeScript avant de lancer les tests,- des sérialiseurs pour permettre la réalisation de tests par comparaison de snapshots,
- des transformateurs AST qui suppriment le CSS de notre composant et qui “inline” le template HTML de nos composants Angular, les rendant ainsi compatibles avec JSDOM.
2. Configurer Jest
Supposons que nous ayons généré une application Angular appelée my-app
avec la commande suivante :
ng new my-app
Créer le fichier de configuration de Jest
Créez le fichier jest.config.js
à la racine de votre projet avec le contenu suivant :
const { pathsToModuleNameMapper } = require('ts-jest/utils');const { compilerOptions } = require('./tsconfig');
module.exports = { preset: 'jest-preset-angular', roots: ['<rootDir>/src/'], testMatch: ['**/+(*.)+(spec).+(ts|js)'], setupFilesAfterEnv: ['<rootDir>/src/test.ts'], collectCoverage: true, coverageReporters: ['html'], coverageDirectory: 'coverage/my-app', moduleNameMapper: pathsToModuleNameMapper(compilerOptions.paths || {}, { prefix: '<rootDir>/', }),};
Le fichier jest.config.js
contient la configuration de Jest. Avec cette configuration, Jest va :
- prendre en comprendre tous les fichiers
.spec.ts
se trouvant dans le dossiersrc
de notre projet, - lire notre fichier de configuration de TypeScript
tsconfig.json
à la recherche d’alias pour qu’on puisse utiliser les alias dans nos tests, - transpiler à la volée notre code TypeScript avant de lancer les tests,
- collecter les informations sur la couverture de code et les écrire dans le dossier
coverage/my-app
.
Mettre à jour le contenu du fichier src/test.ts
Ouvrez le fichier src/test.ts
et remplacer son contenu par :
import 'jest-preset-angular';
Object.defineProperty(window, 'CSS', { value: null });Object.defineProperty(window, 'getComputedStyle', { value: () => { return { display: 'none', appearance: ['-webkit-appearance'], }; },});
Object.defineProperty(document, 'doctype', { value: '<!DOCTYPE html>',});Object.defineProperty(document.body.style, 'transform', { value: () => { return { enumerable: true, configurable: true, }; },});
Ce bout de code fait deux choses :
- Il importe le module JavaScript
jest-preset-angular
pour mettre en place notre environnement de test Angular. - Il “mock” certaines propriétés et fonctions de l’object global
window
pour s’assurer que nos tests peuvent bien tourner dans un environnement JSDOM.
Mettre à jour la configuration TypeScript pour les tests
Ouvrez le fichier tsconfig.spec.json
et mettez à jour son contenu :
{ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/spec", "types": [ "jest", // 1 "node" ], "esModuleInterop": true, // 2 "emitDecoratorMetadata": true // 3 }, "files": ["src/test.ts", "src/polyfills.ts"], "include": ["src/**/*.spec.ts", "src/**/*.d.ts"]}
Ces changements ont pour effets :
- d’instruire le compilateur TypeScript de prendre en compte le fichier de déclarations de types de Jest,
- d’activer l’option
esModuleInterop
du compilateur TypeScript sinon Jest va produire beaucoup d’avertissements dans la console, - d’activer l’option
emitDecoratorMetadata
du compilateur TypeScript sinon l’injection de dépendance d’Angular ne fonctionnera pas avec Jest.
3. Lancer les tests
Vous pouvez maintenant lancer les tests unitaires grâce à la commande suivante :
npx jest
4. Enlever Karma
Nous pouvons maintenant tranquillement enlever Karma de notre projet
Désinstaller Karma
Pour supprimer les dépendances vers Karma et son écosystème, lancer la commande suivante dans un terminal :
npm uninstall karma karma-chrome-launcher karma-coverage-istanbul-reporter karma-jasmine karma-jasmine-html-reporter
Si vous utilisez Yarn, la commande à lancer est :
yarn remove karma karma-chrome-launcher karma-coverage-istanbul-reporter karma-jasmine karma-jasmine-html-reporter
Supprimer le fichier de configuration de Karma
Nous pouvons maintenant supprimer le fichier de configuration de Karma :
rm karma.conf.js
Supprimer le target “test” du ficher “angular.json”
Au lieu de ng test
, nous allons maintenant exécuter npx jest
pour lancer nos tests unitaires. Par conséquent,
le target test
à l’intérieur du fichier angular.json
devient inutile. Vous pouvez donc supprimer la section
projects.my-app.architect.test
du fichier angular.json
:
{ "$schema": "./node_modules/@angular/cli/lib/config/schema.json", "version": 1, "newProjectRoot": "projects", "projects": { "my-app": { "projectType": "application", "schematics": {}, "root": "", "sourceRoot": "src", "prefix": "app", "architect": { "build": { /* config du target build */ }, "serve": { /* config du target serve */ },- "test": {- "builder": "@angular-devkit/build-angular:karma",- "options": {- "main": "src/test.ts",- "polyfills": "src/polyfills.ts",- "tsConfig": "tsconfig.spec.json",- "karmaConfig": "karma.conf.js",- "assets": [- "src/favicon.ico",- "src/assets"- ],- "styles": [- "src/styles.css"- ],- "scripts": []- }- }, "lint": { /* config du target lint*/ }, "e2e": { /* config du target e2e */ } } }}, "defaultProject": "my-app"}
Conclusion
Dans cet article, nous avons vu comment nous pouvons mettre en place Jest pour nos tests unitaires. Cela peut certainement être automatisé à l’aide de schematics Angular, mais ce n’est pas si difficile à faire manuellement.
Vous pouvez par exemple ajouter Jest à votre projet Angular en utilisant les schematics de Briebug en exécutant la commande suivante:
ng add @briebug/jest-schematic
Vous pourrez trouver Le code source complet de cet article dans ce dépôt Github.
Vous aimez ce blog ?
Suivez-moi sur Twitter pour plus de contenu !
Rejoignez la newsletter pour du contenu de grande qualité dans votre boite mail