Tests en JavaScript : Unit, Integration, E2E — Guide complet
La qualité du code est la clé de la réussite de tout projet. Dans le monde JavaScript (notamment Node.js), les tests sont devenus non seulement une bonne pratique, mais une nécessité. Nous analysons trois niveaux clés : les tests unitaires (unit), d'intégration (integration) et de bout en bout (E2E). Vous découvrirez leurs différences, quand appliquer chaque type et verrez des exemples concrets avec des outils populaires.
1. Tests Unitaires : vérifier des modules isolés
Les tests unitaires vérifient le fonctionnement de fonctions, classes ou modules individuels isolés des dépendances externes (base de données, API, système de fichiers). C'est le niveau le plus rapide et le plus fiable.
Outils et configuration
Le framework le plus populaire est Jest. Installation :
npm install --save-dev jestAjoutez le script dans package.json :
"scripts": { "test": "jest"}Exemple : tester une fonction de calcul de remise
Créons un fichier discount.js :
// discount.jsfunction applyDiscount(price, discountPercent) { if (price <= 0) throw new Error('Price must be positive'); if (discountPercent < 0 || discountPercent > 100) throw new Error('Invalid discount'); return price - (price * discountPercent) / 100;}module.exports = { applyDiscount };Écrivons maintenant un test unitaire dans discount.test.js :
const { applyDiscount } = require('./discount');
describe('applyDiscount', () => { test('calculates 10% discount correctly', () => { expect(applyDiscount(100, 10)).toBe(90); });
test('throws error for negative price', () => { expect(() => applyDiscount(-10, 10)).toThrow('Price must be positive'); });
test('throws error for invalid discount percent', () => { expect(() => applyDiscount(100, 150)).toThrow('Invalid discount'); });});Exécution : npm test. Jest trouve automatiquement les fichiers *.test.js.
Conseil : Utilisez des objets mock pour isoler des services externes.
// Exemple de mock d'une API externejest.mock('./api');const api = require('./api');api.getData.mockResolvedValue({ id: 1 });2. Tests d'intégration : vérifier l'interaction des composants
Les tests d'intégration vérifient comment différents modules fonctionnent ensemble : base de données + logique métier + routes HTTP. Ils sont plus lents que les tests unitaires, mais offrent une plus grande confiance dans la correction du système.
Outils : Supertest + Jest
Supertest permet d'effectuer des requêtes HTTP vers votre application Express sans démarrer réellement le serveur.
npm install --save-dev supertestExemple : tester une API REST
Supposons une application Express simple app.js :
const express = require('express');const app = express();app.use(express.json());
app.post('/users', (req, res) => { const { name, email } = req.body; if (!name || !email) { return res.status(400).json({ error: 'Missing fields' }); } // Sauvegarde en BDD (simplifié) res.status(201).json({ id: 1, name, email });});
module.exports = app;Test d'intégration users.test.js :
const request = require('supertest');const app = require('./app');
describe('POST /users', () => { test('creates user with valid data', async () => { const response = await request(app) .post('/users') .send({ name: 'Alice', email: 'alice@test.com' }); expect(response.status).toBe(201); expect(response.body).toHaveProperty('id'); expect(response.body.name).toBe('Alice'); });
test('returns 400 for missing email', async () => { const response = await request(app) .post('/users') .send({ name: 'Bob' });