De nombreux développeurs sont confrontés à des défis lorsqu'il s'agit de tester leur code. Sans tests appropriés, des bogues peuvent passer, entraînant des utilisateurs frustrés et des correctifs coûteux.
Cet article vous montrera comment appliquer efficacement les tests unitaires, d'intégration et de bout en bout à l'aide de Jest, Supertest et Puppeteer sur un exemple très simple construit à l'aide de Node.js et MongoDB.
À la fin de cet article, j'espère que vous comprendrez clairement comment appliquer ces types de tests dans vos propres projets.
?? Veuillez trouver l'exemple complet ici dans ce dépôt.
Avant d'installer nos dépendances, permettez-moi d'abord de vous présenter notre exemple. Il s'agit d'un exemple très simple dans lequel un utilisateur peut ouvrir la page d'inscription, définir ses détails d'inscription, cliquer sur le bouton d'inscription et stocker ses informations dans la base de données.
Dans cet exemple, nous utiliserons les packages suivants :
npm install --save jest express mongoose validator npm install --save-dev jest puppeteer jest-puppeteer mongodb-memory-server supertest npm-run-all
La plupart de ces dépendances sont simples, mais voici des précisions pour quelques-unes d'entre elles :
Bien, traduisons cela en code.
Pour exécuter vos tests unitaires sans comportements imprévisibles, vous devez réinitialiser les fonctions fictives avant chaque test. Vous pouvez y parvenir en utilisant le hook beforeEach :
// setup.unit.js beforeEach(() => { jest.resetAllMocks(); jest.restoreAllMocks(); });
Dans ce cas, nous souhaitons tester la fonction validateInput :
npm install --save jest express mongoose validator npm install --save-dev jest puppeteer jest-puppeteer mongodb-memory-server supertest npm-run-all
C'est une fonction très simple qui valide si l'entrée fournie contient un email valide. Voici son test unitaire :
// setup.unit.js beforeEach(() => { jest.resetAllMocks(); jest.restoreAllMocks(); });
await expect(async () => {}).rejects : sur la base de la documentation de Jest, c'est la façon d'attendre la raison d'une promesse rejetée.
Testons une autre fonction qui vérifie s'il y a un email dupliqué dans la base de données. En fait, celui-ci est intéressant car nous devons gérer la base de données, et en même temps, les tests unitaires ne doivent pas traiter de systèmes externes. Alors que devrions-nous faire alors ? Eh bien, nous devrions utiliser des Mocks.
Tout d’abord, jetez un œil à la fonction emailShouldNotBeDuplicate que nous devons tester :
// register.controller.js const validator = require('validator'); const registerController = async (input) => { validateInput(input); ... }; const validateInput = (input) => { const { name, email, password } = input; const isValidName = !!name && validator.isLength(name, { max: 10, min: 1 }); if (!isValidName) throw new Error('Invalid name'); ... };
Comme vous le voyez, cette fonction envoie une requête à la base de données pour vérifier s'il y a un autre utilisateur ayant le même email. Voici comment nous pouvons nous moquer de l'appel à la base de données :
// __tests__/unit/register.test.js const { registerController } = require('../controllers/register.controller'); describe('RegisterController', () => { describe('validateInput', () => { it('should throw error if email is not an email', async () => { const input = { name: 'test', email: 'test', password: '12345678' }; await expect(async () => await registerController(input)).rejects.toThrow('Invalid email'); }); }); });
Nous nous sommes moqués (espionnés) de la méthode findOne de la base de données en utilisant jest.spyOn(object, methodName) qui crée une fonction simulée et suit ses appels. En conséquence, nous pouvons suivre le nombre d'appels et les paramètres transmis de la méthode findOne espionnée à l'aide de toHaveBeenNthCalledWith.
Avant d'écrire notre test d'intégration, nous devons configurer notre environnement :
npm install --save jest express mongoose validator npm install --save-dev jest puppeteer jest-puppeteer mongodb-memory-server supertest npm-run-all
Maintenant, nous sommes prêts à exécuter notre test d'intégration.
Testons l'ensemble du processus d'inscription côté serveur : de l'envoi de la demande d'inscription au stockage des détails de l'utilisateur dans la base de données et à la redirection vers la page de réussite :
// setup.unit.js beforeEach(() => { jest.resetAllMocks(); jest.restoreAllMocks(); });
Comme vous le voyez, la fonction registerController intègre plusieurs composants (fonctions), les fonctions validateInput, emailShouldNotBeDuplicate et createUser.
Alors, écrivons notre test d'intégration :
// register.controller.js const validator = require('validator'); const registerController = async (input) => { validateInput(input); ... }; const validateInput = (input) => { const { name, email, password } = input; const isValidName = !!name && validator.isLength(name, { max: 10, min: 1 }); if (!isValidName) throw new Error('Invalid name'); ... };
Reprenons notre exemple.
En fait, dans notre exemple, la configuration de l'environnement pour les tests de bout en bout est similaire à celle des tests d'intégration.
Dans ce cas, nous devons simuler exactement le comportement réel d'inscription d'un utilisateur, depuis l'ouverture de la page d'inscription, en remplissant ses coordonnées (nom, email, mot de passe), en cliquant sur le bouton « S'inscrire », et enfin en étant redirigé vers une page de réussite. . Jetez un œil au code :
npm install --save jest express mongoose validator npm install --save-dev jest puppeteer jest-puppeteer mongodb-memory-server supertest npm-run-all
Décomposons ce code :
Photo de Nathan Dumlao sur Unsplash
À ce stade, vous vous demandez peut-être comment exécuter tous les types de tests simultanément lorsque chacun a sa propre configuration. Par exemple :
Alors, comment faire pour exécuter tous les types de tests en même temps tout en s'assurant que chacun respecte sa configuration correspondante ?
Pour résoudre ce problème, suivez ces étapes :
1. Créons trois fichiers de configuration différents, jest.unit.config.js :
// setup.unit.js beforeEach(() => { jest.resetAllMocks(); jest.restoreAllMocks(); });
jest.integration.config.js :
// register.controller.js const validator = require('validator'); const registerController = async (input) => { validateInput(input); ... }; const validateInput = (input) => { const { name, email, password } = input; const isValidName = !!name && validator.isLength(name, { max: 10, min: 1 }); if (!isValidName) throw new Error('Invalid name'); ... };
jest.e2e.config.js :
// __tests__/unit/register.test.js const { registerController } = require('../controllers/register.controller'); describe('RegisterController', () => { describe('validateInput', () => { it('should throw error if email is not an email', async () => { const input = { name: 'test', email: 'test', password: '12345678' }; await expect(async () => await registerController(input)).rejects.toThrow('Invalid email'); }); }); });
2. Ensuite, mettez à jour vos scripts npm dans le fichier package.json comme suit :
// register.controller.js const { User } = require('../models/user'); const registerController = async (input) => { ... await emailShouldNotBeDuplicated(input.email); ... }; const emailShouldNotBeDuplicated = async (email) => { const anotherUser = await User.findOne({ email }); if (anotherUser) throw new Error('Duplicated email'); };
--config : Spécifie le chemin d'accès au fichier de configuration Jest.
npm-run-all --parallel : Permet d'exécuter tous les tests en parallèle.
3. Ensuite, créez trois fichiers d'installation nommés setup.unit.js, setup.integration.js et setup.e2e.js, contenant le code d'installation nécessaire utilisé dans les sections précédentes.
4. Enfin, exécutez tous les tests en exécutant cette commande npm run test. Cette commande exécutera tous les tests unitaires, d'intégration et de bout en bout en parallèle selon leurs configurations respectives.
Dans cet article, nous avons exploré les tests unitaires, d'intégration et de bout en bout (E2E), en soulignant leur importance pour la création d'applications fiables. Nous avons démontré comment implémenter ces méthodes de test à l'aide de Jest, Supertest et Puppeteer dans un exemple simple d'enregistrement d'utilisateur avec Node.js et MongoDB.
En fait, une stratégie de test solide améliore non seulement la qualité du code, mais renforce également la confiance des développeurs et la satisfaction des utilisateurs.
J'espère que cet article vous a fourni des informations utiles que vous pourrez appliquer à vos propres projets. Bon test !
Si vous avez trouvé cet article utile, consultez également ces articles :
Merci beaucoup d'être resté avec moi jusqu'à présent. J'espère que vous apprécierez la lecture de cet article.
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!