Tests unitaires JavaScript faciles dans WordPress avec Jest
WordPress a une longue expérience des tests unitaires de son code PHP. Cependant, écrire des tests unitaires JavaScript et des tests d’intégration pour le code dans les thèmes et les plugins ne bénéficie pas du même statut. Voyons comment tester le JavaScript dans nos plugins et thèmes WordPress en utilisant Jest.
Voici le contenu que nous aborderons dans cet article :
Tests unitaires JavaScript dans WordPress
Alors pourquoi écrire des tests unitaires et des tests d’intégration? Ils sont parfaits pour s’assurer qu’une fonction, une méthode de classe ou même un composant React fait ce qu’il est censé faire. Il aide à détecter les erreurs dans le code et aide également à préserver l’intégrité lorsque des modifications sont introduites ultérieurement dans le code en vérifiant qu’il fonctionne toujours comme prévu après la mise à jour.
Les plugins et thèmes WordPress sont principalement écrits en PHP et peuvent utiliser la suite PHPUnit pour exécuter des tests, faire des assertions, se moquer de fonctions et plus encore. Le manuel contient même une section expliquant comment configurer rapidement les tests unitaires avec le WP-CLI.
Pour JavaScript, il y a une page sur l’exécution des tests QUnit dans le manuel, bien qu’il s’agisse davantage de tester le code JavaScript dans le noyau de WordPress.
Bien que rien de tout cela ne soit standardisé pour JavaScript dans WordPress, nous pouvons écrire d’excellents tests unitaires à l’aide de la suite de tests Jest. Dans cet article, nous allons apprendre à écrire des tests unitaires JavaScript pour un exemple de plugin qui charge 5 messages via l’API WP REST en utilisant la fetch
fonction de JavaScript et les restitue dans un certain élément DOM de la page.
Avantages de l’utilisation de Jest pour les tests unitaires JavaScript dans WordPress
Dans le passé, écrire des tests unitaires JavaScript impliquait de configurer Mocha pour exécuter des tests, Chai pour faire des assertions et Sinon pour simuler des fonctions et les espionner. Bien qu’ils offrent une grande flexibilité, il est beaucoup plus complexe de travailler avec trois packages qu’avec un seul. Jest fournit tout cela dans un seul package :
- vous pouvez exécuter des tests en les déclarant avec
describe
etit
outest
- vous pouvez faire des assertions avec
expect
ettoBe
,toHaveLength
et bien d’autres - vous pouvez simuler des fonctions et les espionner, et il existe plusieurs façons de le faire
Avant d’avancer
Afin de garder cet article concentré sur les tests avec Jest, il existe une configuration supplémentaire externe au processus de test comme Babel ou Webpack qui ne sera pas couverte ici. Tout cela se trouve dans le repo WP Jest Tests qui accompagne cet article. Pour garder les choses contextuelles, chaque section sera liée à l’un des fichiers pertinents que nous écrirons.
Vue d’ensemble du côté PHP
Le PHP du plugin d’exemple que nous allons utiliser pour apprendre à écrire les tests unitaires JavaScript est assez standard. Les seules lignes intéressantes sont celles où nous mettons en file d’attente notre fichier JavaScript et ajoutons un script en ligne pour lui transmettre des variables :
Après avoir enquêté notre fichier JavaScript, nous ajoutons une variable globale wpJestTests
avec wp_add_inline_script()
. Cette variable est particulièrement intéressante et délicate à gérer car elle est externe à notre fichier JavaScript et nous devrons nous en moquer dans nos tests.
Mettre en place des tests Jest
Nous devrons d’abord initialiser npm
notre projet de plugin pour pouvoir installer Jest avec. Naviguez dans la ligne de commande jusqu’au dossier de votre plugin et exécutez :
npm init
et passez par la série d’invites ici
Modifiez le fichier package.json qui a été créé et ajoutez une nouvelle entrée pour exécuter nos tests dans la scripts
section :
"test": "jest"
Ce sera la commande que nous utiliserons pour dire à Jest d’exécuter nos tests unitaires JavaScript. Il s’agit d’une exécution unique, mais Jest prend également en charge la surveillance des fichiers, vous pouvez donc en saisir une supplémentaire :
"test-watch": "jest --watch"
Installez maintenant Jest en tant que dépendance de développement en exécutant
npm install -D jest
Pendant l’installation, créez un fichier nommé jest.config.js
. Cela contiendra toute la configuration nécessaire. Ajoutez ce qui suit :
module.exports = {
verbose: true,
setupFiles: [
'/__mocks__/globals.js'
],
moduleNameMapper: {
'.(css|less|sass|scss)$': '/__mocks__/styleMock.js'
}
};
Passons en revue chacun :
verbose
: indique si chaque test individuel doit être signalé pendant l’exécution. Toutes les erreurs seront également toujours affichées en bas après l’exécution. Notez que s’il n’y a qu’un seul fichier de test en cours d’exécution, il est par défauttrue
.setupFiles
: une liste de chemins vers des modules qui exécutent du code pour configurer ou mettre en place l’environnement de test. Chaque setupFile sera exécuté une fois par fichier de test. Étant donné que chaque test s’exécute dans son propre environnement, ces scripts seront exécutés dans l’environnement de test immédiatement avant d’exécuter le code de test lui-même. Nous l’utiliserons pour déclarer des variables globales rendues par PHP et WordPress avec des commandes telles quewp_add_inline_script
ouwp_localize_script
.moduleNameMapper
: il s’agit d’un mappage d’expressions régulières vers des noms de modules (ou des tableaux de noms de modules) qui permettent de supprimer des ressources statiques, comme des images ou des styles avec un seul module.
Vous avez sûrement remarqué la référence: il s’agit d’un jeton spécial qui est remplacé par Jest par la racine de votre projet, qui est généralement l’emplacement de votre fichier package.json
.
Nous irons en profondeur dans les deux sections suivantes, mais d’abord, créez le dossier et ces deux fichiers référencés ci-dessus :
- créer un dossier nommé
__mocks__
- dans le dossier, créez les fichiers
styleMock.js
etglobals.js
Importation de styles fictifs pour les tests Jest
Si, comme ce plugin, vous utilisez Webpack pour tout compiler y compris les styles et que vous importez le .scss
fichier dans le .js
fichier :
import './main.scss';
vous devez utiliser styleMock.js pour simuler les fichiers SASS lors de leur importation dans notre fichier JavaScript, sinon Jest se bloquera car il ne pourra pas résoudre le module. Vous n’avez pas besoin de beaucoup pour ce fichier, ajoutez simplement
Jest utilisera cette maquette chaque fois qu’il trouvera une .scss
importation et les mappera sur la maquette, vous permettant d’avancer avec des tests sans vous soucier des styles.
Configurer des globales pour Jest
Travaillons maintenant dans le fichier globals.js. L’un des avantages de l’utilisation de Jest, c’est qu’il est déjà livré avec un déjà configuré jsdom
, une implémentation en pur JavaScript des standards Web, qui simule un environnement DOM comme si vous étiez dans le navigateur, et nous l’utiliserons pour simuler des éléments DOM pour nos essais.
Créez un dossier __mocks__
et un globals.js
fichier à l’intérieur. Ajoutez ceci au fichier :
import { JSDOM } from 'jsdom';
const dom = new JSDOM();
global.document = dom.window.document;
global.window = dom.window;
global.window.wpJestTests = undefined;
Cela déclarera et simulera certains objets et méthodes que vous utiliserez plus tard dans vos tests. Le dernier est particulièrement intéressant
global.window.wpJestTests = undefined;
C’est la variable globale que nous avons écrite en utilisant wp_add_inline_script
. Vous devez le simuler en tant que variable globale pour pouvoir l’utiliser dans vos tests.
Présentation du fichier JavaScript
Le plugin WordPress a un seul fichier JavaScript main.js dans un /src
dossier. Ceci est ensuite transpilé et sorti dans un /js/front.js
fichier qui est ce que le PHP va charger. Le JavaScript charge cinq publications WordPress à l’aide fetch
de, une fonction JavaScript standard, via l’API WP REST et insère son titre, avec un lien vers la publication, dans un fichier div.entry-content
.
Vous allez exporter la fonction qui fait tout le travail :
afin que vous puissiez l’utiliser dans vos tests dans Jest.
Écrire des tests unitaires JavaScript avec Jest, enfin !
Vous pouvez maintenant commencer à écrire des tests ! Jest peut trouver des tests de plusieurs manières :
- si le nom du fichier est
test.js
- ou est précédé du nom du fichier qu’il teste, comme
main.test.js
- s’il s’agit
.js
de fichiers situés dans un dossier nommé__tests__
Créez le __tests__
dossier et à l’intérieur, un fichier front.test.js
. Vous pouvez voir le fichier JavaScript terminé pour les tests Jest dans le dépôt compagnon. Parcourons-le en blocs. La première ligne importe le fichier JS que nous voulons tester :
import { wpJestTestsInit } from '../src/main';
Ensuite, nous effaçons tous les mocks, donc nous ne courons jamais avec des mocks sales portant des valeurs de tests précédents. Cela peut entraîner des erreurs car, par exemple, si nous espionnons le nombre de fois qu’une fonction simulée a été appelée, nous pourrions obtenir une lecture incorrecte si nous n’effaçons pas la simulation entre test et test :
Le premier test que nous écrirons, fait des assertions de base lorsque certaines choses échouent. Par exemple, si la variable globale wpJestTests
avec laquelle nous écrivions wp_add_inline_script
n’a pas été écrite pour une raison quelconque :
Dans ce code,
describe
crée un groupe composé de plusieurs tests liéstest
est ce qui effectue réellement un testexpect
enveloppe notre sujet de test en donnant accès à un certain nombre de "matchers" qui vous permettent de faire différentes affirmations sur son contenutoBe
est l’un de ces correspondants. Jest a beaucoup de matchers inclus, et il y en a même d’autres que vous pouvez ajouter avec un package tiers.
Le premier test ne définit rien pour wpJestTests
donc sa valeur sera celle que vous avez définie dans globals.js
. Comme il s’agit de undefined
, nous ne pouvons pas travailler, nous voulons donc confirmer que la fonction revient sans rien faire.
Le deuxième test définit wpJestTests
et se moque de la document.querySelector
méthode à retourner undefined
, qui est ce qu’elle retournerait si elle ne trouvait pas d’élément dans le DOM. Dans ce cas, nous voulons confirmer que nous revenons sans rien faire et que notre fonction mocking document.querySelector
a été appelée une fois.
Récupération simulée dans les tests Jest
La prochaine série de tests commence par
et à l’intérieur, nous avons une autre fonction de démontage :
contrairement à afterEach
celui-ci, il s’exécutera après l’exécution de tous les tests à l’intérieur de ce describe
bloc. Étant donné que notre fichier JavaScript utilise fetch
pour charger les messages, nous devons vérifier qu’il a été appelé et qu’il a renvoyé ce que nous avons demandé, nous allons donc nous moquer de la fetch
fonction :
Nous nous moquons de la première Promise qui se résout à la réponse, et la seconde à une représentation JSON des données. Ces données sont similaires à celles que nous obtenons de l’API WP REST. Étant donné que notre code n’a besoin que du titre et du lien, nous nous moquons de cela.
Test d’intégration JavaScript avec Jest dans un code asynchrone qui utilise fetch
Nous pouvons maintenant écrire le test en utilisant le mocked fetch
. Il y a une différence majeure avec ce test par rapport aux autres tests unitaires JavaScript: il s’agit d’un test d’intégration. Les tests précédents explorés ici garantissaient simplement qu’un composant fonctionnait bien. Nous avons vérifié que si la variable globale d’état initial n’était pas définie, notre composant ne s’afficherait pas. Ceci est différent car nous allons tester le fonctionnement de l’ensemble du système lorsque la variable d’état initiale est définie, déclenchant ainsi une transaction de données, et enfin insérer les titres des articles avec leurs liens dans le document.
Dès le début, c’est différent: la fonction anonyme passée à test
reçoit un done
paramètre. Il s’agit en fait d’une fonction qui sera appelée à la fin du test. Jest attendra done
d’être appelé avant de terminer le test. Si done
n’est jamais appelé, le test échouera avec une erreur de temporisation. C’est intéressant pour nous puisque nous testons du code impliquant fetch
, qui est une fonction asynchrone.
Le global wpJestTests
est défini et notre mocked document.querySelector
renvoie maintenant ce qui ressemble à un élément HTML, avec even classList
et sa add
méthode enfant.
Nous appelons wpJestTestsInit
et nous nous attendons à ce qu’il se termine correctement. Maintenant, puisqu’il fetch
est asynchrone, nous allons utiliser process.nextTick
from Node.js. Le nextTick
in Node.js est la file d’attente qui s’exécutera après la fin de tous les événements de la boucle d’événements actuelle. C’est formidable car toutes nos promesses seraient alors résolues, ce qui est exactement ce dont nous avons besoin pour tester ce code qui implique fetch
.
Les autres sont plus des assertions pour s’assurer querySelector
que quelque chose a été trouvé avec lequel travailler, qui fetch
a bien été appelé, qu’une classe a été ajoutée à la liste, et que les titres et les liens de nos articles ont été insérés dans l’élément HTML correspondant. Une fois que tout est fait, nous appelons done
et notre test asynchrone se termine.
Exécutez vos tests Jest
Maintenant, vous pouvez taper
npm run test
et Jest exécutera les tests unitaires JavaScript pour votre plugin WordPress
Conclusion
So Jest est une solution géniale et simple pour écrire des tests qui couvrent le code JavaScript de nos plugins ou thèmes WordPress. Mais il y a plus. Si nous écrivons une application React pour notre plugin, nous voudrons peut-être faire des affirmations à ce sujet. Jest peut aussi aider jusqu’à un certain point, et si nous avons besoin de plus, nous pouvons ajouter Enzyme à nos outils et commencer à écrire des tests d’intégration avec.
Veuillez faire un don !
Si vous avez trouvé cela utile, n’hésitez pas à m’acheter un café pour que je puisse rester éveillé et créer des tutoriels plus utiles pour vous !
3,00 $