Tests d'intégration JavaScript avec Docker : guide complet
Les tests d'intégration sont une étape critique du développement en JavaScript (Node.js). Ils vérifient l'interaction de votre application avec les services externes : bases de données, API, caches et files d'attente. L'utilisation de Docker à ces fins permet d'isoler l'environnement de test, de garantir sa reproductibilité et d'éviter les problèmes du type "ça marche sur ma machine". Dans cet article, nous allons voir comment configurer les tests d'intégration d'applications JavaScript avec Docker, Docker Compose et les frameworks de test populaires.
Pourquoi Docker est-il nécessaire pour les tests d'intégration ?
Les tests d'intégration traditionnels rencontrent souvent des problèmes : les dépendances peuvent différer selon les machines des développeurs, les bases de données peuvent être dans des états différents, et la configuration de l'environnement prend des heures. Docker résout ces problèmes en offrant :
- Isolation : chaque exécution de test se déroule dans un conteneur propre.
- Reproductibilité : un environnement identique pour tous les développeurs et le CI/CD.
- Vitesse : les conteneurs se lancent en quelques secondes, pas en minutes.
- Gestion des dépendances : il est facile de démarrer PostgreSQL, Redis, RabbitMQ et d'autres services.
Configuration de l'environnement de test avec Docker Compose
Commençons par créer le projet. Supposons que nous ayons une simple application Node.js qui enregistre des données dans PostgreSQL. Créons un fichier docker-compose.test.yml :
version: '3.8'
services: test-runner: build: context: . dockerfile: Dockerfile.test depends_on: - db - redis environment: - NODE_ENV=test - DATABASE_URL=postgresql://testuser:testpass@db:5432/testdb - REDIS_URL=redis://redis:6379 volumes: - ./coverage:/app/coverage
db: image: postgres:15-alpine environment: POSTGRES_USER: testuser POSTGRES_PASSWORD: testpass POSTGRES_DB: testdb ports: - "5432" tmpfs: - /var/lib/postgresql/data
redis: image: redis:7-alpine ports: - "6379"Notez l'utilisation de tmpfs pour PostgreSQL — cela garantit qu'après la fin des tests, les données ne sont pas conservées et que chaque exécution commence avec une base propre.
Dockerfile pour les tests
Créons un Dockerfile.test optimisé pour les tests, et non pour la production :
FROM node:18-alpine
WORKDIR /app
# Copier uniquement package.json pour la mise en cache de la couche des dépendancesCOPY package*.json ./RUN npm ci --only=production && npm ci --only=dev
# Copier le code sourceCOPY . .
# Installer wait-for-it pour attendre que les services soient prêtsADD https://raw.githubusercontent.com/vishnubob/wait-for-it/master/wait-for-it.sh /wait-for-it.shRUN chmod +x /wait-for-it.sh
CMD ["sh", "-c", "/wait-for-it.sh db:5432 -- /wait-for-it.sh redis:6379 -- npm test"]Rédaction de tests d'intégration en JavaScript
Écrivons maintenant les tests eux-mêmes. Utilisons Jest et Supertest pour tester l'API. Créons un fichier tests/integration/user.test.js :
const request = require('supertest');const { app } = require('../src/app');const { Pool } = require('pg');
describe('User API Integration Tests', () => { let pool;
beforeAll(async () => { // Créer un pool de connexions à la base de test pool = new Pool({ connectionString: process.env.DATABASE_URL });
// Exécuter les migrations avant les tests const migrationSQL = ` CREATE TABLE IF NOT EXISTS users ( id SERIAL PRIMARY KEY, name VARCHAR(100) NOT NULL, email VARCHAR(255) UNIQUE NOT NULL, created_at TIMESTAMP DEFAULT NOW() ); `; await pool.query(migrationSQL); });
afterAll(as