
07/04/2023
Eric Dasse
Vitest est un Framework de test unitaire équivalent à Jest, d’ailleurs Vitest utilise la même API que Jest (on pourra retrouver describe
, it
, expect
, …).
Vitest est créé avec Vite, ce qui permet d’avoir le HMR (Hot Module Reloading) pour recharger (à l’enregistrement d’une modification) le fichier modifié, il est en « watch mode » par défaut. Contrairement à Jest, il n’y a pas besoin d’avoir 2 configurations différentes pour Vite et Vitest (tout se fait dans vite.config.js
).
Vitest est une librairie ESM first
, donc il est recommandé d’écrire en ESM (ECMAScript Module), mais fonctionne de base avec du commonjs et ESM.
Il support aussi le TypeScript et JSX de base.
Vitest (v0.28.5) nécessite Vite >= v3.0.0 et Node >= v14
(Il faut regarder la doc pour voir les compatibilités des versions)
Pour ajouter Vitest à un projet, il faut taper la commande suivante :
Ensuite il faut ajouter la commande pour lancer les tests dans package.json :
En créant un premier test on peut déjà voir une différence avec Jest :
Vitest n’importe pas automatiquement les globals (contrairement à Jest), donc si on veut passer un projet de Jest à Vitest il y a 2 solutions :
CONFIGURATION : vite.config.ts
En mettant en place cette configuration il faudra, pour que TypeScript fonctionne avec les API globales, ajouter les lignes suivantes dans le fichier tsconfig.ts :
Maintenant vous pouvez avoir (ou garder) vos tests sans importer les méthodes :
Personnellement je préfère importer les méthodes directement dans le fichier de test.
Vitest fournit des tests Snapshot
:
Il est possible aussi d’ajouter des Inline Snapshot
, ce qui permet d’enregistrer le résultat directement dans le fichier de test :
Une fois le test lancé, au lieu de créer un fichier Snapshot, Vitest modifiera le répertoire du fichier de test, automatiquement, pour mettre à jour le Snapshot sous forme de chaîne :
Cela permet de voir directement la sortie attendue sans naviguer entre différents fichiers.
Vitest utilise @sinonjs/fake-timers un package pour manipuler les timers, ainsi que la date système. Vous pouvez en savoir plus sur l’API spécifique en détail ici.
Exemple :
(tiré de la doc)
Comme dans Jest les fonctions de mock ( spyOn et fn ) sont disponibles avec Vitest mais, pour les appeler, il faudra utiliser vi
au lieu de jest
: vi.spyOn()
et vi.fn()
.
Exemple :
(tiré de la doc)
Il est possible de mocker des variables globales qui ne sont pas présentes avec jsdom
ou node
en utilisant le helper vi.stubGlobal
.
Exemple :
(tiré de la doc)
Maintenant on peut accéder à la variable IntersectionObserverMock
dans nos tests.
Voir la section api vi.mock() pour une description détaillée de l’API.
Vitest a un algorithme d’automocking, c’est-à-dire, que si votre code importe un module mocké, sans aucun fichier associé à mocks
ou factory
pour ce module, alors Vitest mockera le module lui-même en l’invoquant et en simulant chaque exportation.
Les principes suivants s’appliquent :
Étant donné que Vitest s’exécute dans Node, mocker des requêtes réseau est délicat, les API Web ne sont pas disponibles, nous avons donc besoin de quelque chose qui imitera le comportement du réseau pour nous. Vitest recommande Mock Service Worker pour y parvenir. Il permettra de mocker à la fois des APIs REST et GraphQL, et est indépendant du framework.
Mock Service Worker (MSW) fonctionne en interceptant les requêtes de vos tests, vous permettant de l’utiliser sans modifier le code de votre application. Dans le navigateur, cela utilise l’API Service Worker. Dans Node.js, et pour Vitest, il utilise node-request-interceptor. Pour en savoir plus sur MSW, voir leur introduction.
Exemple de configuration :
(tiré de la doc)
*La configuration du serveur avec onUnhandleRequest: 'error'
garantit qu’une erreur est renvoyée chaque fois qu’une requête n’a pas de gestionnaire de requêtes correspondant.
La couverture de tests se fait avec la commande vitest --coverage
:
Pour avoir le rapport de couverture de test on peut utiliser c8, istanbul ou une solution de couverture personnalisée (comme indiqué sur la documentation).
En lançant cette commande (sans avoir installer de lib au préalable), cela demandera si on veut installer la dépendance c8 :
Une fois installer voici le résultat :
On peut remarquer que cela nous a généré un dossier coverage avec plusieurs fichiers :
Dans le fichier vite.config.ts
il est possible d’ajouter une configuration pour demander le rapport de la couverture de tests uniquement en text
(le rapport dans la console), json
ou html
par exemple.
Voici un exemple du rapport en html :
Dans le rapport en html, on peut aussi naviguer dans les fichiers pour voir le code couvert :
Vite permet à Vitest de fournir une interface utilisateur qui s’exécute dans le navigateur (il faudra ajouter la dépendance code>@vitest/ui</code). Il peut afficher du code, afficher les erreurs, afficher des graphiques, …
Pour cela, nous allons ajouter vitest --ui
dans le package.json :
En lançant cette commande on nous demande d’installer la dépendance code>@vitest/ui</code:
(Il est possible aussi d’ajouter la dépendance avec la commande npm i -D @vitest/ui
)
Une fois installer on peut relancer la commande, cela nous ouvre une page web (http://localhost:51204/vitest/) :
On peut naviguer dans les fichiers tests et on aura plusieurs options :
Dans la partie « Code » on peut voir le code de test et le modifier (toujours en watch mode) :
Si le test tombe en erreur cela l’indiquera tout de suite :
Vitest est riche en fonctionnalités, simple à mettre en place et s’accorde parfaitement avec Vite. De plus, se basant sur la même API que Jest, on a pu voir qu’il était facile de passer les tests d’une application de Jest à Vitest.
Allez-vous l’utiliser pour vos tests ?