Integrationstests für TypeScript mit Docker: Fortgeschrittenes Niveau
Integrationstests sind ein entscheidender Schritt in der Entwicklung moderner TypeScript-Anwendungen. Wenn Ihr System aus vielen Mikrodiensten, Datenbanken, Nachrichtenwarteschlangen und externen APIs besteht, decken isolierte Unit-Tests die realen Interaktionsszenarien nicht mehr ab. Docker ermöglicht die Erstellung reproduzierbarer, isolierter Umgebungen für Tests, die der Produktion nahekommen. In diesem Artikel betrachten wir fortgeschrittene Techniken für Integrationstests von TypeScript-Anwendungen mit Docker: von der Konfiguration der Container bis zum Aufbau von CI/CD-Pipelines.
Warum Docker das ideale Werkzeug für Integrationstests von TypeScript ist
Traditionelle Ansätze für Integrationstests leiden oft unter Umgebungsproblemen: "Auf meinem Rechner funktioniert es". Docker löst dieses Problem, indem es Folgendes bietet:
- Isolation – jeder Test wird in einem sauberen Container ausgeführt, ohne Einfluss auf andere Prozesse
- Reproduzierbarkeit – gleiche Umgebung in allen Phasen: lokal, im CI, auf Staging
- Geschwindigkeit – leichtgewichtige Container starten in Sekunden
- Flexibilität – einfache Kombination verschiedener DB-Versionen, Caches, Warteschlangen
Für TypeScript-Projekte ist Docker besonders nützlich, da es ermöglicht, nicht nur die Node.js-Laufzeitumgebung zu testen, sondern auch die Interaktion mit dem TypeScript-Compiler, der Transpilation und dem Build-Prozess.
Einrichtung der Docker-Umgebung für TypeScript-Tests
Beginnen wir mit der grundlegenden Konfiguration. Erstellen wir ein Dockerfile für den Produktions-Build und ein separates für Tests:
# Dockerfile.testFROM node:18-alpine AS builder
WORKDIR /appCOPY package*.json ./RUN npm ciCOPY tsconfig.json ./COPY src/ ./src/
# TypeScript-BuildRUN npm run build
# Phase für 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 ./
# Integrationstests startenCMD ["npx", "jest", "--config", "jest.config.ts", "--testMatch", "**/*.integration.test.ts"]Zur Verwaltung mehrerer Dienste verwenden wir 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: bridgeSchreiben fortgeschrittener Integrationstests in TypeScript
Jetzt erstellen wir einen Test, der ein vollständiges Szenario überprüft: Schreiben in die DB, Caching in Redis und Senden eines Ereignisses an die Warteschlange. Wir verwenden die Bibliothek testcontainers zur dynamischen Verwaltung von Containern aus TypeScript-Code:
// tests/integration/user-registration.integration.test.tsimport { GenericContainer, StartedTestContainer, Wait } from 'testcontainers';import { PostgreSqlContainer } from '@testcontainers/postgresql';import { RedisContainer } from '@testcontainers/redis';import axi