Der Code in diesem Repository ist die Grundlage für die Live-Coding-Session "API-Tests, Contract-Tests, Consumer-driven Contract-Tests – alles dasselbe?".
Ziel der Session ist es, die Grundlagen und Konzepte der verschiedenen Test-Varianten zu verstehen. Es ist kein Tool-Deep-Dive und auch keine Tool-Empfehlung. Die vorgestellten Konzepte lassen sich mit unterschiedlichen Tools und Frameworks in unterschiedlichen Programmiersprachen umsetzen.
Für die Live-Demo werden Java 25, Spring Boot 4.0 und Pact 4.6 verwendet.
- DevLand 2026, 13.03.2026 (PDF)
- JavaLand 2026, 10.03.2026 (PDF)
Das Projekt beinhaltet sowohl den Client/Consumer als auch den Server/Provider. Beide bringen ihr eigenes Modell mit separaten Datentypen mit. Die Struktur beider Modelle ist zunächst identisch, wird sich aber im Verlauf der Live-Demo verändern.
Folgende Schritte werden in der Live-Demo vorgeführt:
➡️ Der Server/Provider testet seine eigene Wetter-API integrativ, d.h. mit laufendem Server:
- Im WetterController befindet sich der API-Endpoint des Providers.
- Wir starten die Application, damit der Server/Provider läuft.
- Über die Swagger-UI testen wir die API manuell.
- (optional) API über den IntelliJ-HTTP-Client testen.
➡️ Der Client/Consumer testet die Provider-API:
- ClientApiTest ausführen (sollte grün sein).
- Server (Application) stoppen.
- Test nochmal ausführen (sollte nun rot sein).
➡️ (optional) Der Server/Provider testet seine eigene Wetter-API simuliert, d.h. ohne laufenden Server:
- ServerApiTest ausführen (sollte grün sein - ohne laufenden Server).
➡️ Consumer-driven Contract-Testing: Ohne Contracts hat der Provider (noch) nichts zum Verifizieren.
- ProviderPactTest ausführen.
- Sollte mit der Fehlermeldung "No Pact files were found to verify" abbrechen, weil es noch keine Contracts im entsprechenden Verzeichnis gibt.
➡️ Consumer-driven Contract-Testing: Der Consumer testet seinen Aufruf gegen eine simulierte API ("Mock") – und erzeugt nebenbei die Contract-Datei.
- ConsumerPactTest ausführen (sollte grün sein).
- Contract-Datei sollte nun im entsprechenden Verzeichnis vorhanden sein.
➡️ Consumer-driven Contract-Testing: Der Provider kann seine API nun erfolgreich verifizieren und die API kann kompatibel erweitert werden.
- Der ProviderPactTest sollte nun grün sein.
- Wir erweitern die Wetter-API, ergänzen im WetterInfo-Record
als drittes Feld die Wetterlage und lassen den
WetterController konstant
Wetterlage.SONNEzurückliefern. - Der ProviderPactTest sollte immer noch grün sein!
➡️ Consumer-driven Contract-Testing: Eine inkompatible API-Änderung führt zum Fehlschlag der Verifikation.
- Nun bauen wir eine inkompatible API-Änderung ein.
- In der Temperatur ändern wir den Datentyp
intaufString. - Im WetterController ergänzen wir den
temp-Wert um die Zeichenkette " °C". - Spätestens beim Versuch, den ProviderPactTest auszuführen, wird ein Compiler-Fehler im
ServerApiTest gemeldet. Wir "fixen" den Bug, indem
wir das
isBetween(-20, 40)durchendsWidth(" °C")ersetzen. - Der ProviderPactTest sollte nun fehlschlagen und auf inkompatible Datentypen hinweisen.
➡️ (optional) Consumer-driven Contract-Testing: Wenn der Client einen inkompatiblen Contract erwartet, schlägt die Verifikation beim Provider fehl.
- Die inkompatible API-Änderung von oben zurückdrehen. Nun ändern wir den Consumer-Contract inkompatibel.
- In die ConsumerTemperatur bauen wir als zweites Feld des Records die ConsumerEinheit ein.
- Der ConsumerPactTest ist zunächst noch grün. Wir
müssen dort eine weitere Assertion einbauen, die bei der Temperatur die
ConsumerEinheit.CELSIUSerwartet. - Nun ist der ConsumerPactTest rot, weil die "gemockte" Antwort oben in der Klasse nicht mehr passt.
- In der LambdaDsl oben in der Klasse ersetzen wir die Zeile für die Temperatur mit folgendem Code:
body.object("temperatur", temperatur -> { temperatur.integerType("wert", 15); temperatur.stringType("einheit", "CELSIUS"); }); - Der ConsumerPactTest sollte nun wieder grün sein - und eine neue Contract-Datei schreiben.
- Der ProviderPactTest sollte nun rot sein.