Tests d'intégration TypeScript avec Docker : niveau avancé
\n\nLes tests d'intégration sont une étape clé pour vérifier l'interaction des composants d'un système. Pour les applications TypeScript, en particulier dans une architecture de microservices, Docker devient un outil indispensable. Dans cet article, nous explorerons des techniques avancées de configuration et d'exécution de tests d'intégration avec Docker, qui vous aideront à améliorer la fiabilité et la rapidité de développement.
\n\n1. Pourquoi Docker pour les tests d'intégration TypeScript ?
\nDocker permet d'isoler les environnements de test, garantissant leur reproductibilité. Au lieu de configurer manuellement des bases de données, des files d'attente de messages et autres dépendances, vous les exécutez dans des conteneurs. Cela est particulièrement important pour les projets TypeScript, où le typage peut masquer des erreurs d'exécution qui apparaissent précisément lors de l'intégration.
\n- \n
- Isolation : chaque test s'exécute dans un environnement propre \n
- Vitesse : les conteneurs se lancent en quelques secondes \n
- Parallélisme : possibilité de tester simultanément différentes versions des dépendances \n
2. Configuration de Docker Compose pour l'environnement de test
\nCréons un fichier docker-compose.test.yml qui démarre PostgreSQL, Redis et l'application elle-même pour les tests :
version: '3.8'\nservices:\n db-test:\n image: postgres:15-alpine\n environment:\n POSTGRES_DB: testdb\n POSTGRES_USER: test\n POSTGRES_PASSWORD: testpass\n ports:\n - "5433:5432"\n tmpfs: /var/lib/postgresql/data\n\n redis-test:\n image: redis:7-alpine\n ports:\n - "6380:6379"\n\n app-test:\n build:\n context: .\n dockerfile: Dockerfile.test\n environment:\n DATABASE_URL: postgres://test:testpass@db-test:5432/testdb\n REDIS_URL: redis://redis-test:6379\n depends_on:\n - db-test\n - redis-test\n command: ["npm", "run", "test:integration"]\nIci, nous utilisons tmpfs pour la base de données afin que les données ne soient pas conservées entre les exécutions, ce qui accélère les tests.
3. Configuration avancée des tests TypeScript avec TestContainers
\nLa bibliothèque testcontainers permet de gérer les conteneurs directement depuis le code TypeScript. Cela offre une flexibilité : vous pouvez démarrer des conteneurs uniquement pour certains scénarios de test.
Installation :
\nnpm install --save-dev testcontainers\nExemple de test d'intégration avec un conteneur dynamique :
\nimport { GenericContainer, StartedTestContainer } from 'testcontainers';\nimport { Client } from 'pg';\nimport { UserService } from './user-service';\n\nlet container: StartedTestContainer;\nlet client: Client;\n\nbeforeAll(async () => {\n // Démarrage du conteneur PostgreSQL\n container = await new GenericContainer('postgres:15-alpine')\n .withEnvironment({\n POSTGRES_DB: 'test',\n POSTGRES_USER: 'test',\n POSTGRES_PASSWORD: 'test'\n })\n .withExposedPorts(5432)\n .start();\n\n // Connexion à la base de données de test\n const host = container.getHost();\n const port = container.getMappedPort(5432);\n client = new Client({\n host,\n port,\n database: 'test',\n user: 'test',\n password: 'test'\n });\n await client.connect();\n\n // Exécution des migrations\n await client.query(`\n CREATE TABLE users (\n id SERIAL PRIMARY KEY,\n email VARCHAR(255) UNIQUE NOT NULL,\n name VARCHAR(255)\n )\n `);\n});\n\nafterAll(async () => {\n await client.end();\n await container.stop();\n});\n\ntest('UserService.createUser crée un utilisateur dans la base de données', async () => {\n const userService = new UserService(client);\n const user = await userService.createUser({\n email: 'test@example.com',\n name: 'Test User'\n });\n\n const result = await client.query('SELECT * FROM users WHERE email = $1', ['test@example.com']);\n expect(result.rows[0]).toMatchObject({\n email: 'test@example.com',\n