Tests d'intégration TypeScript avec Docker : niveau avancé
Les tests d'intégration sont une étape clé dans le développement d'applications TypeScript modernes. Lorsque votre système est composé de nombreux microservices, bases de données, files d'attente de messages et API externes, les tests unitaires isolés ne couvrent plus les scénarios d'interaction réels. Docker permet de créer des environnements de test reproductibles et isolés, proches de la production. Dans cet article, nous aborderons les techniques avancées de tests d'intégration d'applications TypeScript avec Docker : de la configuration des conteneurs à la construction de pipelines CI/CD.
Pourquoi Docker est l'outil idéal pour les tests d'intégration TypeScript
Les approches traditionnelles des tests d'intégration souffrent souvent de problèmes d'environnement : "ça marche sur ma machine". Docker résout ce problème en offrant :
- L'isolation — chaque test s'exécute dans un conteneur propre, sans influence sur les autres processus
- La reproductibilité — un environnement identique à toutes les étapes : local, CI, staging
- La rapidité — des conteneurs légers qui se lancent en quelques secondes
- La flexibilité — combinaison facile de différentes versions de bases de données, caches, files d'attente
Pour les projets TypeScript, Docker est particulièrement utile car il permet de tester non seulement le runtime Node.js, mais aussi l'interaction avec le compilateur TypeScript, la transpilation et la construction.
Configuration de l'environnement Docker pour les tests TypeScript
Commençons par la configuration de base. Créons un Dockerfile pour la build de production et un autre pour les tests :
# Dockerfile.testFROM node:18-alpine AS builder
WORKDIR /appCOPY package*.json ./RUN npm ciCOPY tsconfig.json ./COPY src/ ./src/
# Construction TypeScriptRUN npm run build
# Étape pour les testsFROM node:18-alpine AS test-runnerWORKDIR /appCOPY --from=builder /app/dist ./distCOPY --from=builder /app/node_modules ./node_modulesCOPY --from=builder /app/package.json ./COPY tests/ ./tests/COPY jest.config.ts ./
# Lancement des tests d'intégrationCMD ["npx", "jest", "--config", "jest.config.ts", "--testMatch", "**/*.integration.test.ts"]Pour gérer plusieurs services, utilisons docker-compose.yml :
version: '3.8'services: app: build: context: . dockerfile: Dockerfile.test depends_on: postgres: condition: service_healthy redis: condition: service_healthy environment: - DB_HOST=postgres - DB_PORT=5432 - REDIS_HOST=redis - REDIS_PORT=6379 volumes: - ./tests:/app/tests:ro networks: - test-network
postgres: image: postgres:15-alpine environment: POSTGRES_DB: testdb POSTGRES_USER: testuser POSTGRES_PASSWORD: testpass healthcheck: test: ["CMD-SHELL", "pg_isready -U testuser -d testdb"] interval: 5s timeout: 5s retries: 5 networks: - test-network
redis: image: redis:7-alpine healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 networks: - test-network
networks: test-network: driver: bridgeRédaction de tests d'intégration avancés en TypeScript
Créons maintenant un test qui vérifie un scénario complet : écriture en base de données, mise en cache dans Redis et envoi d'un événement dans une file d'attente. Utilisons la bibliothèque testcontainers pour la gestion dynamique des conteneurs depuis le code TypeScript :
// tests/integration/user-registration.integration.test.tsimport { GenericContainer, StartedTestContainer, Wait } from 'testcontainers';import { PostgreSqlContainer } from '@testcontainers/postgresql';import { RedisContainer } from '@testcontainers/redis';import axi