Integrationstests von JavaScript mit Docker: Vollständiger Leitfaden
Integrationstests sind ein kritisch wichtiger Schritt in der JavaScript-Entwicklung (Node.js). Sie überprüfen die Interaktion Ihrer Anwendung mit externen Diensten: Datenbanken, APIs, Caches und Warteschlangen. Die Verwendung von Docker für diese Zwecke ermöglicht es, die Testumgebung zu isolieren, ihre Reproduzierbarkeit zu gewährleisten und Probleme mit "es funktioniert auf meinem Rechner" zu vermeiden. In diesem Artikel werden wir besprechen, wie man Integrationstests für JavaScript-Anwendungen mit Docker, Docker Compose und beliebten Test-Frameworks einrichtet.
Warum wird Docker für Integrationstests benötigt?
Traditionelle Integrationstests stehen oft vor Problemen: Abhängigkeiten können sich auf verschiedenen Entwicklerrechnern unterscheiden, Datenbanken können sich in unterschiedlichen Zuständen befinden, und die Einrichtung der Umgebung nimmt Stunden in Anspruch. Docker löst diese Probleme, indem es Folgendes bereitstellt:
- Isolation: Jeder Testlauf erfolgt in einem sauberen Container.
- Reproduzierbarkeit: Gleiche Umgebung für alle Entwickler und CI/CD.
- Geschwindigkeit: Container starten in Sekunden, nicht Minuten.
- Abhängigkeitsverwaltung: Einfaches Hochfahren von PostgreSQL, Redis, RabbitMQ und anderen Diensten.
Einrichtung der Testumgebung mit Docker Compose
Beginnen wir mit der Erstellung des Projekts. Angenommen, wir haben eine einfache Node.js-Anwendung, die Daten in PostgreSQL speichert. Erstellen wir eine Datei 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"Beachten Sie tmpfs für PostgreSQL – dies stellt sicher, dass nach Abschluss der Tests keine Daten gespeichert werden und jeder Lauf mit einer sauberen Datenbank beginnt.
Dockerfile für Tests
Erstellen wir ein Dockerfile.test, das für Tests optimiert ist, nicht für die Produktion:
FROM node:18-alpine
WORKDIR /app
# Nur package.json kopieren, um die Abhängigkeitsebene zu cachenCOPY package*.json ./RUN npm ci --only=production && npm ci --only=dev
# Quellcode kopierenCOPY . .
# wait-for-it für das Warten auf die Bereitschaft der Dienste installierenADD 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"]Schreiben von Integrationstests in JavaScript
Jetzt schreiben wir die Tests selbst. Wir verwenden Jest und Supertest zum Testen der API. Erstellen wir eine Datei 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 () => { // Verbindungspool zur Testdatenbank erstellen pool = new Pool({ connectionString: process.env.DATABASE_URL });
// Migrationen vor den Tests ausführen 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