EMZETT.
Login

Contract-Tests und Testcontainers: Integration realistisch testen

Kurz: Contract-Tests prüfen, dass Dienste sich an vereinbarte Schnittstellen halten; Testcontainers starten echte Datenbanken und Dienste für Tests in Docker.

Genauer: Zwischen Unit-Tests (isoliert) und E2E-Tests (alles zusammen) liegen Integrationstests: Verstehen sich Komponenten? Zwei Werkzeuge machen sie praktikabel.

Im Detail

Das Problem

Mocks lügen: Wer die Datenbank im Test durch ein Mock ersetzt, merkt nicht, wenn die echte SQL-Abfrage fehlerhaft ist oder sich die API des anderen Teams ändert. Dennoch sollen Tests schnell und wiederholbar bleiben.

Testcontainers

Die Bibliothek Testcontainers (Java, JavaScript, Python, Go, .NET) startet Docker-Container für die Dauer eines Tests: echte PostgreSQL, Redis, Kafka, Elasticsearch.

from testcontainers.postgres import PostgresContainer
 
with PostgresContainer("postgres:16") as pg:
    url = pg.get_connection_url()
    # Tabelle anlegen, Code gegen echte DB testen

Vorteile: realistisch, jeder Test hat eine saubere Umgebung, kein manuelles Aufsetzen; Aufräumen übernimmt die Bibliothek. Nachteile: braucht Docker, etwas langsamer als Mocks. Alternative: docker-compose in der CI.

Contract-Tests

Zwei Dienste (Konsument und Anbieter) einigen sich auf einen Vertrag: Aufbau von Anfragen und Antworten. Consumer-driven Contracts (zum Beispiel mit Pact): Der Konsument beschreibt, was er braucht; der Anbieter prüft in seiner CI, dass er das liefert. Ändert der Anbieter etwas Unverträgliches, schlägt sein Test fehl, bevor er in Produktion geht. Auch OpenAPI-Spezifikationen lassen sich als Vertrag nutzen, mit Tools, die Antworten gegen das Schema prüfen.

Wann was?

  • Viele Unit-Tests für Logik.
  • Integrationstests mit Testcontainers für Datenbankzugriffe, Migrationen, Queues.
  • Contract-Tests zwischen Teams/Microservices.
  • Wenige E2E-Tests für Hauptwege. So bleibt die Testpyramide schnell und aussagekräftig. Halte Testdaten klein, vermeide gegenseitige Abhängigkeiten zwischen Tests und räume Ressourcen zuverlässig auf.

Siehe auch: Testpyramide, Mocking und Test-Doubles, OpenAPI und Swagger, Docker