Start / Seminare / Moderne API-Entwicklung mit REST, OpenAPI und Contract Testing

Modul

Consumer-driven Contract Testing mit Pact

4 Kapitel in diesem Modul-Video · Laufzeit

Vertonung mit synthetischer Stimme · Inhalte redaktionell verantwortet · © 2026 HECKER CONSULTING, alle Rechte vorbehalten

Transkript

Der gesprochene Text dieses Moduls zum Mitlesen, Überfliegen und Durchsuchen. Ein Klick auf einen Zeitstempel springt an die Stelle im Video.

Consumer-driven Contract Testing mit Pact

0:00 Wir haben zwei Tage lang an einem Vertrag gearbeitet, der beschreibt, was eine API alles kann. Jetzt kommt ein Werkzeug mit einer anderen Perspektive — und die ist erstaunlich befreiend. Pact beschreibt nicht, was Ihre API kann, sondern was ein bestimmter Consumer tatsächlich braucht. Alles Übrige dürfen Sie ändern. Das klingt nach einer Einschränkung und ist in Wahrheit die Grundlage dafür, dass Sie eine API weiterentwickeln können, ohne bei jeder Änderung alle Beteiligten zu fragen.

Consumer-driven Contract Testing mit Pact

0:29 Drei Etappen. Zuerst die Idee: Warum lässt man den Consumer den Vertrag schreiben, und was ist der Unterschied zu einer OpenAPI-Beschreibung? Dann die Mechanik — wie aus einem Consumer-Test eine Pact-Datei entsteht und wie der Provider sie verifiziert. Und zum Schluss der Teil, der Contract Testing erst wirklich nützlich macht: der Pact Broker und die Frage, ob eine Version deployt werden darf.

Warum Consumer-driven

0:53 Beginnen wir mit der Denkweise. Sie unterscheidet sich grundlegend von allem, was wir gestern gemacht haben — und beide Ansätze ergänzen sich, statt sich zu widersprechen. Denn die eine Sicht beschreibt Möglichkeiten, die andere die tatsächliche Nutzung. Erst beides zusammen ergibt ein vollständiges Bild Ihrer Schnittstelle.

1:12 Der Begriff, den die Pact-Dokumentation dafür verwendet, ist Vertrag durch Beispiel. Statt zu beschreiben, was theoretisch möglich ist, hält der Vertrag konkrete Interaktionen fest: Dieser Consumer schickt diese Anfrage und erwartet diese Antwort. Und das Entscheidende: Er entsteht während der automatisierten Consumer-Tests, wird also nicht geschrieben, sondern fällt an.

1:33 Damit kann er nichts enthalten, was der Consumer nicht wirklich aufruft. Für Sie als Provider heißt das: Was in keinem Pact steht, dürfen Sie ändern. Die dritte Zeile ist die aufschlussreichste. Eine OpenAPI-Beschreibung sagt nichts darüber, wer Ihre API wie nutzt — sie beschreibt Möglichkeiten. Ein Pact-Vertrag zeigt jeden Consumer und was er tatsächlich braucht.

1:56 Das ist eine Information, die Sie sonst nirgends bekommen und die bei jeder Änderungsentscheidung Gold wert ist. Beide Arten schließen sich nicht aus. Die OpenAPI-Beschreibung ist Ihr Angebot, die Pacts sind die tatsächliche Nutzung. Sie brauchen beides — für Verschiedenes. Alle vier Punkte kennen Sie vermutlich aus eigener Erfahrung. Der erste ist der teuerste: Alle Dienste gleichzeitig lauffähig, in zueinander passenden Ständen.

2:23 In einer Landschaft mit fünfzehn Diensten ist das ein Vollzeitjob. Der zweite ist der frustrierendste — ein roter Lauf, und niemand weiß, wer schuld ist. Und der vierte beschreibt, warum das Problem mit der Größe wächst: Der Abstimmungsaufwand steigt schneller als der Nutzen. Genau an dieser Stelle setzt Contract Testing an.

2:43 Der zweite Punkt ist der wichtigste in diesem Modul, deshalb halte ich mich dort auf. Wenn ein Consumer Fälle testet, die er nie aufruft, bindet er den Provider an Zusagen, die niemand braucht. Der Provider kann dann etwas nicht ändern, obwohl es niemandem nützt. Das ist genau das Gegenteil dessen, was Pact erreichen will. Der vierte Punkt ist eine Erwartungskorrektur: Pact ersetzt nicht Ihre OpenAPI-Beschreibung.

3:08 Die Dokumentation sagt das ausdrücklich — es sind zwei verschiedene Arten von Vertrag.

Verträge erzeugen und verifizieren

3:14 Jetzt zur Mechanik. Der Ablauf besteht aus zwei getrennten Läufen mit zwei verschiedenen Verantwortlichen — und dazwischen liegt eine Datei. Zwei Läufe, zwei Verantwortliche, dazwischen eine Datei — mehr ist es nicht. Sehen wir uns an, was in jedem der beiden Läufe passiert und wo der Berührungspunkt liegt. Der Ablauf ist elegant.

3:35 Im Consumer-Test läuft ein Mock Provider, und dagegen arbeitet der echte Client-Code — nicht ein Testdouble, sondern die Klasse, die später auch in Produktion die Anfrage stellt. Das ist wichtig, denn nur so beschreibt der entstehende Vertrag wirklich, was der Consumer tut. Aus den erwarteten Interaktionen entsteht die Pact-Datei.

3:53 Der Provider nimmt sie später, spielt die Anfragen gegen seine laufende Anwendung ein und vergleicht die echten Antworten mit den Erwartungen. Achten Sie auf den Provider State im ersten Schritt — er ist der Teil, der in der Praxis die meisten Fragen aufwirft. Der Consumer sagt damit: Meine Erwartung gilt unter der Voraussetzung, dass eine bestätigte Bestellung mit dieser Kennung existiert.

4:16 Der Provider muss diesen Zustand vor der Verifikation herstellen. Das ist der Berührungspunkt zwischen beiden Seiten, und er muss abgesprochen sein — ein frei formulierter Zustand, den der Provider nicht herstellen kann, blockiert die ganze Verifikation. Hier liegt der Unterschied zwischen einem brauchbaren und einem lästigen Pact.

4:35 Ein Matcher prüft, dass ein Feld vorhanden und vom richtigen Typ ist — nicht, dass es einen bestimmten Wert hat. Warum das zählt: Der Provider stellt für die Verifikation seinen eigenen Zustand her, und die Kennungen dort sind andere als in Ihrem Consumer-Test. Feste Werte würden bei jedem Lauf scheitern. Der vierte Punkt erklärt, warum trotzdem ein Beispielwert dabei ist: Der Mock Provider muss dem Consumer ja etwas antworten können.

5:01 Der erste und der vierte Punkt sind die häufigsten in der Praxis. Feldwerte zu prüfen, die den Consumer nicht interessieren, macht den Vertrag brüchig — die Pact-Dokumentation warnt ausdrücklich vor Über-Spezifikation. Der zweite Punkt ist die Variante davon für Validierungen: Für jede Fehlervariante eine eigene Interaktion.

5:20 Die Empfehlung lautet, genau eine zu schreiben, die zeigt, wie der Provider auf etwas Falsches antwortet. Und der vierte ist ein Organisationsfehler: Eine Pact-Datei, die den Provider nie erreicht, ist wirkungslos. Dafür gibt es den Broker.

Broker, Versionierung und Freigaben

5:36 Damit sind wir beim Teil, der Contract Testing von einer netten Idee zu einem Werkzeug macht, das Deployments absichert. Es geht um eine einzige Frage: Darf diese Version raus? Denn Verträge zu erzeugen und zu verifizieren ist erst die halbe Miete. Erst wenn ihr Ergebnis eine Deployment-Entscheidung trägt, wird daraus eine echte Absicherung.

5:56 Der Broker ist mehr als ein Dateiablage. Er hält Verträge und Verifikationsergebnisse zusammen und baut daraus eine Matrix: Welche Consumerversion wurde gegen welche Providerversion erfolgreich geprüft? Diese Matrix ist die Grundlage für eine Entscheidung, die sonst Bauchgefühl ist. Sie beantwortet nämlich nicht nur, ob Ihre Tests grün waren, sondern ob Ihre Version mit dem zusammenpasst, was in der Zielumgebung tatsächlich läuft.

6:22 Und das ist eine deutlich schärfere Frage. Zwei Befehle, und die Reihenfolge ist der Kern. Der erste meldet dem Broker, was gerade wo läuft — ohne diese Information hat er keinen Bezugspunkt. Der zweite stellt die eigentliche Frage: Darf diese neue Version in diese Umgebung? Der Broker schaut nach, gegen welche Stände sie geprüft wurde, vergleicht mit dem, was dort läuft, und antwortet mit ja oder nein.

6:47 Wichtig ist die Reihenfolge im Alltag: Wer das Melden vergisst, bekommt Antworten auf Basis eines veralteten Bildes. Der zweite Punkt ist die Regel, die alles trägt: Fehlt ein erfolgreiches Verifikationsergebnis, lautet die Antwort nein. Nicht vielleicht, nicht mit Warnung — nein. Das ist streng und genau richtig, denn eine fehlende Prüfung ist keine bestandene Prüfung.

7:09 Der dritte Punkt löst ein zeitliches Problem der Praxis: Wenn der Providerlauf noch läuft, wartet die Option retry-while-unknown darauf, statt sofort abzubrechen. Und der vierte ist wichtig für größere Landschaften: Mehrere Consumer werden einzeln geprüft, nicht als Gruppe. Der erste Punkt ist derselbe Fehler wie bei den Quality Gates gestern, nur teurer: Die Freigabe läuft und hält nichts auf.

7:33 Der zweite ist der spezifische Pact-Fehler — Deployments werden nicht gemeldet, und die Matrix beschreibt einen Zustand von vor drei Monaten. Der dritte ist ein Hygieneproblem, das mit der Zeit kommt: Jeder Feature-Zweig veröffentlicht Verträge, und irgendwann weiß niemand mehr, welche noch relevant sind. Legen Sie früh fest, welche Zweige veröffentlichen dürfen.

Übung

7:54 Jetzt bauen Sie das selbst — und zwar bis zu dem Moment, auf den es ankommt: Jemand entfernt ein Feld, und der Vertrag schlägt an, bevor irgendetwas deployt ist. Sie werden dabei beide Fälle sehen — den, in dem die Verifikation zu Recht rot wird, und den, in dem sie zu Recht grün bleibt. Der Unterschied ist der ganze Gewinn.

8:14 Die Kunden-App der Hofkiste braucht die Bestellübersicht. Ihre Aufgabe ist, diese Erwartung als Consumer-Test zu formulieren, die entstehende Pact-Datei anzusehen und sie providerseitig zu verifizieren. Danach entfernen Sie ein Feld, das der Consumer nutzt — die Verifikation muss fehlschlagen. Und dann kommt der lehrreichere Teil als Erweiterung: Entfernen Sie ein Feld, das der Consumer nicht nutzt. Die Verifikation muss grün bleiben.

8:40 Genau dieser Unterschied ist der Gewinn von Consumer-driven Contract Testing. Nehmen Sie sich für Schritt drei einen Moment Zeit und schauen Sie sich die erzeugte Pact-Datei wirklich an. Sie ist gut lesbares JSON, und wer einmal hineingesehen hat, versteht das ganze Verfahren besser als nach jeder Erklärung. Schritt fünf ist die eigentliche Pointe: Der rote Lauf ist hier das gewünschte Ergebnis.

9:03 Lesen Sie die Fehlermeldung genau — sie nennt Ihnen das Feld und den Consumer, der es braucht. Das ist die Information, die Ihnen ein End-to-End-Test nie so klar liefert. Der erste Punkt ist der Matcher-Fehler aus dem zweiten Kapitel, hier in der Praxis: feste Bezeichner in der Erwartung. Die Verifikation scheitert dann am Provider-Zustand, nicht an einem echten Bruch.

9:25 Der zweite Punkt ist die andere Hälfte davon — ein Provider State, der beim Provider nicht hergestellt wird. Und der dritte ist der klassische Anfängerfehler, den man in der Erweiterung dieser Übung direkt spürt: Wer Felder erwartet, die er gar nicht liest, bindet den Provider ohne Grund.

Lieber mit Trainer? Dieses Modul ist Teil unserer Team-Schulungen — mit Übungen, Ihrem eigenen Code und Fragen, die ein Video nicht beantwortet. Mehr erfahren →