Integrationstests von JavaScript mit Docker: fortgeschrittene Techniken

Online Python-Trainer für Anfänger

Lernen Sie Python einfach ohne theoretische Überlastung. Lösen Sie praktische Aufgaben mit automatischer Überprüfung und schreiben Sie Code direkt im Browser.

Kurs starten

Integrationstests von JavaScript mit Docker: von der Theorie zur fortgeschrittenen Praxis

\n\n

Integrationstests sind eine kritisch wichtige Phase der Entwicklung, die die Interaktion zwischen verschiedenen Modulen und externen Diensten überprüft. Für JavaScript-Anwendungen auf Node.js wird Docker zu einem unverzichtbaren Werkzeug, das die Erstellung isolierter, reproduzierbarer Umgebungen für Tests ermöglicht. In diesem Artikel betrachten wir fortgeschrittene Techniken zur Einrichtung von Integrationstests mit Docker, einschließlich der Arbeit mit Datenbanken, Warteschlangen und der Optimierung für CI/CD.

\n\n

Warum Docker für Integrationstests?

\n\n

Traditionelle Ansätze für Integrationstests (Mocks, Stubs) spiegeln nicht immer das tatsächliche Verhalten des Systems wider. Docker löst dieses Problem, indem es Folgendes bietet:

\n\n
    \n
  • Isolation: Jeder Test wird in einem sauberen Container ausgeführt, ohne andere Tests oder die lokale Umgebung zu beeinflussen.
  • \n
  • Reproduzierbarkeit: Gleiche Ausführungsbedingungen auf dem Entwicklerrechner und in CI/CD.
  • \n
  • Skalierbarkeit: Möglichkeit zum parallelen Ausführen von Tests mit verschiedenen Versionen von Abhängigkeiten (PostgreSQL, Redis, Elasticsearch).
  • \n
  • Schnelle Wiederherstellung: Das Neuerstellen von Containern dauert Sekunden, nicht Stunden der Einrichtung.
  • \n
\n\n

Einrichtung einer fortgeschrittenen Testumgebung

\n\n

Betrachten wir eine typische Node.js-Anwendung, die PostgreSQL und Redis verwendet. Anstelle einer einfachen docker-compose.yml erstellen wir eine flexible Konfiguration mit Unterstützung für parallele Tests und Health Checks.

\n\n

Schritt 1: Docker Compose mit dynamischen Ports

\n\n

Um Portkonflikte bei paralleler Ausführung zu vermeiden, verwenden wir dynamische Zuweisung:

\n\n
# docker-compose.test.yml\nversion: '3.8'\nservices:\n  postgres_test:\n    image: postgres:15-alpine\n    environment:\n      POSTGRES_DB: test_db\n      POSTGRES_USER: test_user\n      POSTGRES_PASSWORD: test_pass\n    ports:\n      - "0:5432"  # Dynamischer Port\n    healthcheck:\n      test: ["CMD-SHELL", "pg_isready -U test_user -d test_db"]\n      interval: 2s\n      timeout: 5s\n      retries: 10\n    tmpfs: /var/lib/postgresql/data  # Daten im RAM für Geschwindigkeit\n\n  redis_test:\n    image: redis:7-alpine\n    ports:\n      - "0:6379"\n    healthcheck:\n      test: ["CMD", "redis-cli", "ping"]\n      interval: 2s\n      timeout: 5s\n      retries: 10
\n\n

Schritt 2: Hilfsprogramme zum Ausführen von Tests mit Docker

\n\n

Wir erstellen eine Hilfsklasse, die automatisch dynamische Ports findet und auf die Bereitschaft der Dienste wartet:

\n\n
// test/setup/docker-manager.js\nconst { DockerComposeEnvironment, Wait } = require('testcontainers');\nconst { Client } = require('pg');\nconst Redis = require('ioredis');\n\nclass DockerTestManager {\n    constructor() {\n        this.environment = null;\n        this.config = {\n            pgPort: null,\n            redisPort: null\n        };\n    }\n\n    async start() {\n        this.environment = await new DockerComposeEnvironment(\n            '.', \n            'docker-compose.test.yml'\n        ).withWaitStrategy('postgres_test', Wait.forHealthCheck())\n         .withWaitStrategy('redis_test', Wait.forHealthCheck())\n         .up();\n\n        // Port-Mapping extrahieren\n        const pgContainer = this.environment.getContainer('postgres_test');\n        const redisContainer = this.environment.getContainer('redis_test');\n        \n        this.config.pgPort = pgContainer.getMappedPort(5432);\n        this.config.redisPort = redisContainer.getMappedPort(6379);\n        \n        return this.config;\n    }\n\n    async stop() {\n        if (this.environment) {\n            await this.environment.down();\n        }\n    }\n}\n\nmodule.exports = DockerTestManager;
\n\n

Fortgeschrittene Szenarien für Integrationstests

\n\n

Kommen wir nun zu konkreten Tests, die die tatsächliche Interaktion der Komponenten überprüfen.

\n

Blogs

Buchempfehlungen