Start / Seminare / Java Testing mit JUnit, Mockito und Testcontainers

Modul

Komplexe Testumgebungen, Pipelines und KI-Unterstützung

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.

Testumgebungen, Pipelines und KI

0:00 Das letzte Modul bringt alles zusammen. Wir bauen eine Testumgebung aus mehreren Diensten, überführen sie in eine Pipeline und stellen zum Schluss die unbequemste Frage des ganzen Seminars: Was sind unsere Tests eigentlich wert? Der Satz auf der Folie ist mein Maßstab dafür — eine Testsuite ist erst fertig, wenn sie auf einem fremden Rechner dasselbe sagt wie auf dem eigenen.

0:21 Alles andere ist eine persönliche Gewohnheit, kein Sicherheitsnetz. Und ganz am Ende sehen wir uns an, wo KI-Assistenten dabei helfen und wo sie nur beschäftigen.

Komplexe Testumgebungen, Pipelines und KI-Unterstützung

0:31 Das Abschlussmodul. Zuerst mehrere Dienste im Verbund, dann die Pipeline mit ihren eigenen Regeln, und zum Schluss die Beurteilung der Testgüte samt kontrolliertem KI-Einsatz. Danach legen wir die Landkarte aus dem ersten Modul noch einmal daneben.

Mehrere Dienste im Verbund testen

0:46 Fangen wir mit der Erweiterung an, die uns seit dem sechsten Modul fehlt: Der externe Dienst wird zum Container, nicht zum Mock. Bis hierher hatten wir einen Container. Jetzt kommen mehrere dazu: ein Broker für Nachrichten, ein Cache, und für fremde HTTP-Schnittstellen eine programmierbare Attrappe, die selbst im Container läuft.

1:06 Das Neue daran ist nicht die Menge, sondern die Verbindung untereinander. Container bekommen ein gemeinsames Netzwerk und feste Namen darin, und darüber sprechen sie miteinander — so wie in einem echten Verbund. Das ist der Punkt, an dem eine Testumgebung anfängt, der Produktionsumgebung wirklich zu ähneln. Und es ist auch der Punkt, an dem man aufpassen muss, dass sie nicht ausufert.

1:28 Vier Schichten, und jede hat eine Aufgabe. Ganz oben die Anwendung selbst. Darunter die Zahlwerk-Attrappe — programmierbar, im Container, und damit endlich eine echte HTTP-Gegenstelle statt eines Mocks. Dann Broker und Cache. Und ganz unten PostgreSQL in derselben Version wie in Produktion. Was diese Anordnung zeigt: Nur die zweite Schicht ist eine Attrappe, alles andere ist echt.

1:53 Das ist ein deutlich anderes Bild als am zweiten Tag, wo fünf Mocks im Aufbau standen. Und es ist auch das Bild, mit dem Sie in einem Projekt gut leben können. Der entscheidende Teil sind die beiden Zeilen in der Mitte: das gemeinsame Netzwerk und der Netzwerk-Alias. Damit bekommt der Container einen Namen, unter dem die anderen Container ihn erreichen.

2:14 Und hier liegt die häufigste Verwirrung: Innerhalb des Netzwerks lautet die Adresse zahlwerk und der interne Port. Von außen, also aus Ihrem Test heraus, gilt der zufällig gemappte Port. Zwei verschiedene Sichten auf denselben Dienst. Wer das einmal verstanden hat, spart sich eine lange Fehlersuche mit Verbindungsmeldungen, die keinen Sinn ergeben.

2:35 Zwei Wege, dieselbe Umgebung zu beschreiben. Im Java-Code haben Sie feinere Kontrolle, besonders bei den Wartebedingungen je Container. Mit einer Compose-Datei beschreiben Sie die Umgebung einmal und können sie auch für die lokale Entwicklung nutzen. Die letzte Zeile nennt die praktische Grenze: bis etwa vier Dienste einzeln, darüber lohnt Compose.

2:55 Und die Fußzeile enthält den eigentlichen Rat: Wer die Compose-Datei ohnehin pflegt, sollte sie nicht im Testcode ein zweites Mal beschreiben. Zwei Beschreibungen derselben Umgebung laufen garantiert irgendwann auseinander. Der erste Punkt ist die Adressverwechslung, die wir eben besprochen haben — Container sprechen über den Alias, nicht über localhost.

3:16 Der zweite betrifft die Attrappe: Ihre Regeln werden je Test neu gesetzt und nie abgeräumt, und dann antwortet sie im nächsten Test noch nach der alten Regel. Der dritte ist verschenkte Zeit: Broker und Datenbank starten nacheinander, obwohl sie nichts voneinander wissen. Und der vierte ist eine Frage des Maßes — der Verbund wächst auf sechs Container, und geprüft wird trotzdem nur ein Endpunkt. Dann stimmt das Verhältnis nicht mehr.

Tests in der CI/CD-Pipeline

3:41 Jetzt geht es in die Pipeline. Und dort gilt eine andere Priorität als auf Ihrem Rechner: nicht Geschwindigkeit, sondern Reproduzierbarkeit. In der Pipeline entscheidet nicht die Testqualität über den Nutzen, sondern die Reproduzierbarkeit. Dieselben Images, dieselbe Java-Version, dieselbe Reihenfolge — sonst vergleichen Sie zwei verschiedene Läufe miteinander.

4:04 Für die Laufzeit gibt es zwei zusätzliche Lebenszyklen jenseits der Klasse. Ein Singleton-Container startet einmal je Testlauf statt je Klasse. Und wiederverwendbare Container überleben sogar den Testlauf. Der zweite ist ein sehr angenehmes Werkzeug für die lokale Arbeit — und ausdrücklich nicht für die Pipeline gedacht, weil dort jeder Lauf sauber beginnen soll.

4:26 Diese Tabelle ordnet, was wir über drei Module verteilt gesehen haben. Ganz oben die maximale Isolation, die selten nötig ist. Dann der Regelfall: ein statisches Feld je Testklasse. Darunter der Singleton für Situationen, in denen viele Klassen dieselbe Datenbank nutzen — das spart in großen Suiten spürbar Zeit. Und ganz unten die Wiederverwendung über den Testlauf hinaus.

4:48 Die Fußzeile ist hier wichtiger als die Tabelle: Diese Funktion gilt weiterhin als experimentell und wird für Pipelines ausdrücklich nicht empfohlen. Nutzen Sie sie lokal, wenn Sie den gleichen Test zwanzigmal starten. Das ist mir der wichtigste Punkt in diesem Kapitel. Ein sporadisch roter Test hat immer eine Ursache: Zeit, Reihenfolge, Nebenläufigkeit oder Netz. Immer eine dieser vier.

5:12 Wer ihn stattdessen wiederholt, bis er grün wird, hat die Ursache nicht beseitigt, sondern nur in die Produktion verschoben — dort gibt es keinen zweiten Versuch. Eine Pipeline sollte solche Tests deshalb kennzeichnen und ihre Quote sichtbar machen, statt sie stillschweigend erneut auszuführen. Drei automatische Wiederholungen kosten drei Laufzeiten und erzeugen ein Sicherheitsgefühl, das nicht gedeckt ist.

5:36 Bevor jemand Tests aus der Pipeline nimmt, lohnt der Blick auf die Wartezeiten. Ein nicht zwischengespeichertes Image wird bei jedem Lauf neu geladen — bei einer Datenbank sind das schnell mehrere hundert Megabyte. Auch die Abhängigkeiten des Builds gehören in den Cache. Und hier zahlt sich das feste Image-Tag ein zweites Mal aus: Nur was eine feste Kennung hat, lässt sich sinnvoll zwischenspeichern.

5:59 Der letzte Punkt ist wieder derselbe Rat wie gestern: Messen Sie zuerst, wie viel Ihrer Pipeline-Laufzeit reine Wartezeit ist. Oft ist es mehr als die Hälfte. Der erste Punkt ist der gefährlichste, weil er grün aussieht: Auf dem Agenten fehlt die Container-Laufzeit, alle Container-Tests werden übersprungen, und die Pipeline meldet Erfolg.

6:19 Prüfen Sie deshalb die Zahl der ausgeführten Tests, nicht die Farbe. Der zweite ist der Singleton, der nie gestoppt wird und Daten über Klassengrenzen trägt. Der dritte ist ein Unterschied, der lange unbemerkt bleibt: Wiederverwendung lokal aktiv, in der Pipeline nicht — dann verhalten sich die Tests an beiden Orten anders.

6:37 Und der vierte ist die automatische Wiederholung, deren Quote niemand sieht.

Qualität beurteilen und KI kontrolliert einsetzen

6:42 Und damit zur letzten und unbequemsten Frage: Woher wissen Sie, ob Ihre Tests etwas taugen? Die Abdeckung allein beantwortet das nicht. Abdeckungswerkzeuge messen, welcher Code ausgeführt wurde — Anweisungen, Zeilen, Zweige, Pfade. Das ist nützlich und wird regelmäßig missverstanden. Eine hohe Abdeckung ist kein Qualitätsnachweis, denn ausgeführt ist nicht geprüft. Ein Test ohne einzige Assertion erzeugt hervorragende Abdeckungswerte.

7:10 Entscheidend bleibt, ob die Tests relevante Verhaltensweisen und Fehlerszenarien überprüfen. Genau das misst Mutation Testing: Es verändert den Code gezielt — aus größer wird größer-gleich — und schaut nach, ob überhaupt ein Test rot wird. Das ist die ehrlichere Frage. Vier Zähler, und sie sind unterschiedlich aussagekräftig. Anweisungen und Zeilen sind die bekanntesten und die schwächsten.

7:35 Die Fußzeile nennt den Grund: Eine Zeile mit einer Bedingung wird von einem einzigen Testfall als abgedeckt gezählt, obwohl nur einer von zwei Zweigen gelaufen ist. Deshalb ist die Zweigabdeckung die aussagekräftigere Zahl, und die Pfadabdeckung geht noch einen Schritt weiter. Wenn Sie in Ihrem Projekt nur eine Kennzahl beobachten wollen, nehmen Sie die Zweige. Und wenn Sie eine Grenze setzen, setzen Sie sie dort — nicht auf die Zeilen.

8:00 Diese Gegenüberstellung erklärt, warum beide Werkzeuge nebeneinander Sinn ergeben. Abdeckung fragt: Wurde die Zeile ausgeführt? Mutation Testing fragt: Fällt der Test auf, wenn der Code falsch ist? Die erste Frage ist schnell zu beantworten und gehört in jeden Build. Die zweite dauert lange und gehört in einen nächtlichen Lauf oder auf einzelne Module.

8:21 Die letzte Zeile ist der eigentliche Grund für den Aufwand: Abdeckung lässt sich leicht schönen, Mutation Testing kaum. Wer eine Zahl braucht, an der niemand drehen kann, findet sie hier. Ein KI-Assistent ist beim Finden von Grenzfällen wirklich gut — er sieht Kombinationen, die man beim Schreiben übersehen hat, und er ermüdet nicht.

8:41 Aber er hat einen strukturellen blinden Fleck: Er kennt Ihre fachliche Regel nicht. Er leitet die Erwartung aus dem vorhandenen Code ab. Und das heißt, ein generierter Test schreibt im Zweifel das aktuelle Verhalten fest — einschließlich des Fehlers, den Sie eigentlich suchen. Deshalb die Regel, die ich Ihnen mitgeben möchte: Übernommen wird ein Vorschlag erst, wenn jemand seine fachliche Aussage in einem Satz benennen kann.

9:06 Der erste Punkt ist die Quote als Selbstzweck: Achtzig Prozent werden erzwungen, und es entstehen Tests ohne Assertion, die genau diese Quote erfüllen. Der zweite ist eine verpasste Auswertung — die Abdeckung wird gemessen, aber nie mit den tatsächlichen Fehlern der letzten Monate verglichen. Dabei wäre das die interessanteste Auswertung überhaupt. Der dritte ist die Massenübernahme generierter Tests, nach der niemand mehr weiß, was die Suite eigentlich aussagt.

9:32 Und der vierte ist ein Aufwandsproblem: Mutation Testing über die ganze Anwendung dauert zu lange und wird nach zwei Wochen abgeschaltet.

Übung

9:40 Die letzte Übung schließt den Kreis. Wir bringen die Testumgebung in die Pipeline und prüfen zum Schluss, ob unsere Tests halten, was sie versprechen. Erinnern Sie sich an das sechste Modul? Dort haben Sie Zahlwerk gemockt und notiert, welche Aussage der Test dadurch verliert. Genau diese Lücke schließen wir jetzt: Der Zahlungsdienst bekommt eine echte HTTP-Gegenstelle im Container.

10:03 Dazu kommt die Pipeline mit Reports — und der interessanteste Teil des Erfolgskriteriums: Ein absichtlicher Fehler muss die Pipeline nachweislich rot färben. Das klingt trivial und ist die einzige echte Prüfung, die Sie für eine Testsuite haben. Alles andere ist Vertrauen. Die ersten beiden Schritte sind Aufbau: die Attrappe im Container und die Pipeline mit Reports und Abdeckung.

10:26 Schritt drei ist die Prüfung — ein Breaking Change, und dann die Frage, welcher Test ihn meldet. Die Fußzeile sagt, warum das der wichtigste Schritt ist: Meldet ihn keiner, fehlt ein Test, und Sie haben das ohne Produktionsvorfall herausgefunden. Schritt vier und fünf holen den KI-Assistenten dazu — er schlägt vor, Sie prüfen fachlich, und übernommen wird nur, was eine eigene Aussage trifft.

10:49 Diese Reihenfolge ist nicht verhandelbar. Der erste Punkt entwertet die ganze Prüfung: Der Breaking Change wird so gewählt, dass er garantiert auffällt. Nehmen Sie einen, bei dem Sie sich nicht sicher sind — nur dann lernen Sie etwas. Der zweite betrifft die Attrappe: Antwortet sie immer gleich, bleibt der Fehlerfall ungeprüft, und der ist meist der interessantere.

11:11 Der dritte ist die Übernahme von KI-Vorschlägen, weil sie grün sind. Grün ist kein Argument. Und der vierte ist der stille Tod jeder Kennzahl — der Report wird erzeugt und nach dem ersten Lauf nie wieder gelesen. Damit endet unser Seminar: Prüfen Sie Ihre Tests so kritisch, wie Sie Ihren Code prüfen.

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