Start / Seminare / Modern Java Development

Modul

Tests und Debugging im Migrationskontext

5 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.

Tests und Debugging im Migrationskontext

0:00 Über Tests ließe sich ein eigenes Seminar füllen, und es gibt eines. Hier geht es um einen sehr bestimmten Ausschnitt: das Netz, das eine Migration braucht. Nicht flächendeckende Absicherung, nicht Teststrategie, nicht Werkzeugkunde. Sondern die Frage, wie Sie mit vertretbarem Aufwand genau dort absichern, wo der Migrationsplan Risiko ausweist.

0:21 Und wie ein Agent Ihnen dabei hilft, ohne dass am Ende hundert grüne Tests dastehen, die nichts prüfen.

Tests und Debugging im Migrationskontext

0:28 Wir bewerten zuerst die Absicherung fachlich, statt Prozente zu zählen. Dann halten wir bestehendes Verhalten fest — auch das fragwürdige. Danach spannen wir das Netz gezielt entlang der Risikostellen aus dem Migrationsplan. Und zum Schluss arbeiten wir einen echten Fehler ab, in einer Reihenfolge, die wichtiger ist als der Fehler selbst.

0:47 Teststrategie im Ganzen, Ende-zu-Ende-Tests und Berichtswesen bleiben ausdrücklich außen vor — dafür gibt es das Seminar zu GenAI in der Qualitätssicherung. Vier Ziele. Erstens: Absicherung fachlich bewerten statt Abdeckung zu zählen — das ist ein anderer Blick auf dieselben Zahlen. Zweitens: bestehendes Verhalten festhalten, bevor die Migration es ändert. Drittens: gezielt dort absichern, wo der Plan Risiko ausweist, und nur dort.

1:13 Und viertens: Fehler mit dem Agenten in der richtigen Reihenfolge abarbeiten. Bei allen vier Punkten gilt dieselbe Grundhaltung: Wir nutzen das Werkzeug für die Fleißarbeit und behalten die Bewertung bei uns.

Fehlende Testfälle finden lassen

1:27 Beginnen wir mit einer Umstellung der Frage. Die übliche Kennzahl für Absicherung ist die Testabdeckung, und sie ist bequem, weil sie eine Zahl liefert. Nur beantwortet sie nicht die Frage, die uns interessiert. Wir stellen deshalb eine andere — und Sie werden sehen, dass eine andere Frage auch eine ganz andere Art von Antwort erzeugt.

1:47 Eine Abdeckungszahl sagt, welche Zeilen bei den Tests ausgeführt wurden. Sie sagt nichts darüber, ob dabei etwas geprüft wurde. Man kann achtzig Prozent Abdeckung haben und keinen einzigen Grenzfall abgesichert — es reicht, den Code durchlaufen zu lassen. Das ist wie eine Sicherheitsprüfung, die zählt, wie viele Räume betreten wurden, statt was kontrolliert wurde.

2:08 Die nützlichere Frage lautet deshalb: Welche fachlichen Fälle kommen in den Tests nicht vor? Und die kann man tatsächlich stellen. Das Entscheidende an diesem Auftrag steht in den letzten beiden Zeilen: die Gliederung. Normalfall, Grenzwert, ungültige Eingabe, Fehlerfall. Wenn Sie diese Kategorien vorgeben, bekommen Sie eine Antwort entlang dieser Kategorien — und damit eine Liste, mit der Sie arbeiten können.

2:34 Ohne Gliederung bekommen Sie einen Fließtext mit Empfehlungen. Das ist eine allgemeine Technik, die weit über Tests hinaus gilt: Die Struktur Ihrer Frage bestimmt die Struktur der Antwort. Wer eine Tabelle will, muss die Spalten nennen. Der dritte Punkt ist der, den Sie in Ihrem eigenen Projekt bestätigt finden werden: Grenzwerte und Fehlerfälle fehlen im Bestand am häufigsten.

2:57 Der Normalfall ist immer getestet — den hat man beim Entwickeln vor Augen. Was fehlt, ist die leere Liste, die Null, das ungültige Datum. Und genau das sind die Fälle, bei denen sich zwischen Java-Ständen etwas geändert haben könnte. Der vierte Punkt macht daraus einen Arbeitsauftrag: Die Liste priorisiert, wo zuerst abgesichert wird.

3:17 Der zweite Punkt ist die Falle für die Gründlichen: alle gefundenen Lücken schließen wollen. Die Liste wird lang sein — in einem gewachsenen Projekt findet sich immer noch ein ungetesteter Fall. Wenn Sie alle schließen, sind Sie in vier Wochen fertig und haben nicht migriert. Der letzte Punkt sagt, wonach Sie stattdessen auswählen: Testlücken suchen, ohne den Migrationsplan zu kennen, ist Beschäftigung.

3:40 Der Plan sagt Ihnen, welche zwanzig Prozent der Lücken tatsächlich zählen.

Charakterisierungstests für Bestandscode

3:45 Im zweiten Kapitel geht es um eine Testsorte, die viele nicht kennen und die für genau diese Situation gemacht ist. Ihr Zweck ist nicht, richtiges Verhalten zu sichern. Ihr Zweck ist, aktuelles Verhalten festzuhalten — ausdrücklich auch dann, wenn es fachlich falsch ist. Das klingt beim ersten Hören widersinnig, und deshalb lohnt sich hier eine Minute Erklärung, bevor wir sie schreiben.

4:07 Ein Charakterisierungstest ist kein Qualitätsurteil, sondern ein Foto. Er hält fest, was die Anwendung heute tut — richtig oder falsch, das ist nicht die Frage. Sein Zweck ist ein einziger: Er schlägt an, wenn die Migration das Verhalten ändert. Stellen Sie sich vor, Sie fotografieren eine Wohnung vor dem Umzug. Nicht weil sie schön ist, sondern damit Sie hinterher sehen, was fehlt.

4:30 Genau diese Rolle spielt dieser Test — und deshalb hat er auch ein Verfallsdatum, wenn die Migration durch ist. Beachten Sie den Kommentar in diesem Test — er ist wichtiger als die Zusicherung darunter. Dort steht, dass das festgehaltene Verhalten fachlich fraglich ist. Ohne diesen Kommentar passiert nämlich das, was die Fußzeile sagt: In sechs Monaten liest jemand diesen Test und hält ihn für eine fachliche Zusage.

4:55 Dann wird aus einem Foto eine Vorschrift, und niemand traut sich mehr, das eigentlich falsche Verhalten zu korrigieren. Ein Satz Kommentar verhindert das dauerhaft. Der zweite Punkt ist der, weshalb ein Agent hier wirklich hilft: Er leitet bestehendes Verhalten schneller ab als ein Mensch. Das ist stumpfe, mühsame Arbeit — Code lesen, Fälle durchspielen, Erwartungswerte notieren. Genau die Sorte Aufgabe, bei der ein Werkzeug glänzt und ein Mensch ermüdet.

5:22 Der dritte Punkt ist der angenehme Nebeneffekt: Fragwürdiges Verhalten wird sichtbar, ohne dass Sie es sofort ändern müssen. Sie dokumentieren es, und die fachliche Diskussion kann später stattfinden. Der zweite Punkt ist der, der das ganze Netz entwertet: das Verhalten nebenbei korrigieren. Sie schreiben den Test, sehen, dass das Ergebnis falsch ist, und bessern schnell aus.

5:45 Damit haben Sie kein Foto mehr, sondern ein gemaltes Bild — und nach der Migration wissen Sie nicht, ob eine Abweichung von der Migration kommt oder von Ihrer Korrektur. Erst festhalten, dann migrieren, dann korrigieren. Der letzte Punkt ist die Mengenfrage: nicht flächendeckend charakterisieren, sondern entlang des Plans.

JUnit-Tests als Migrationsnetz

6:05 Im dritten Kapitel wird das Netz konkret. Wir spannen es nicht überall, sondern genau an den Stellen, die der Migrationsplan aus dem letzten Modul als riskant ausweist. Damit wird aus einer unbezahlbaren Aufgabe eine bezahlbare — und das ist der eigentliche Trick an dieser Stelle. Es geht nicht darum, mehr zu testen. Es geht darum, gezielter zu testen und den Rest bewusst offen zu lassen.

6:29 Flächendeckende Absicherung eines gewachsenen Projekts ist ein Jahresprojekt. Das bekommen Sie nicht bewilligt, und Sie brauchen es auch nicht. Was Sie brauchen, ist Absicherung an den Stellen, an denen sich zwischen zwei Java-Ständen tatsächlich etwas ändern kann: geändertes API-Verhalten, Zeit und Zeitzone, Zeichensatz, Zahlenformate, Nebenläufigkeit, Sortierung.

6:50 Das ist eine überschaubare Liste. Und der Migrationsplan sagt Ihnen bereits, welche davon in Ihrem Projekt vorkommen. Die Logik dieser Tabelle: Links steht die Risikostelle, rechts, was der Test tatsächlich prüfen muss — nicht irgendetwas, sondern genau das Verhalten, das sich ändern kann. Meine Empfehlung wäre, sich die letzte Zeile besonders anzusehen, und die Fußzeile sagt auch warum: Sortierreihenfolge bei Gleichstand ändert sich zwischen Ständen erstaunlich oft.

7:18 Das trifft dann eine Auswertung, in der Positionen mit gleichem Datum plötzlich anders herum stehen. Fachlich falsch, technisch unauffällig, und ohne Test findet es die Buchhaltung. Der dritte Punkt ist der, mit dem Sie diese Arbeit begründen können: Jeder dieser Tests bleibt nach der Migration wertvoll. Das unterscheidet ihn vom Charakterisierungstest, der ein Verfallsdatum hat. Ein Test für Zeitzonenverhalten oder Rundung ist danach dauerhaft nützlich.

7:44 Sie bauen also nicht nur ein Gerüst, sondern ein Stück bleibende Substanz. Und der letzte Punkt ist der, der die Migration überhaupt erst zu einem beherrschbaren Vorhaben macht: Erst das Netz macht sie zurücknehmbar. Der erste Punkt ist der subtilste des ganzen Moduls: Tests schreiben, die dieselbe Annahme wie der Code treffen.

8:04 Wenn Sie den Erwartungswert aus dem ableiten, was der Code gerade tut, prüfen Sie nur, dass er weiterhin dasselbe tut — das ist bei Charakterisierungstests gewollt und bei Risikotests wertlos. Der zweite Punkt ist der Klassiker: zeitabhängige Tests, die nur in einer Zeitzone grün sind. Wenn Ihre Pipeline auf einem Server mit anderer Zeitzone läuft, merken Sie das.

8:25 Wenn nicht, merkt es später jemand anders.

Generierte Tests bewerten

8:28 Im vierten Kapitel kommt der Punkt, an dem die Begeisterung über generierte Tests eine Bremse braucht. Tests erzeugen zu lassen ist einfach geworden, und das Ergebnis sieht beeindruckend aus — zwanzig Tests in zwei Minuten, alle grün, die Abdeckungszahl steigt. Die Frage ist nur, ob darin auch etwas behauptet wird. Und die beantworten wir jetzt, an einem Beispiel, das Ihnen bekannt vorkommen dürfte.

8:53 Ein Test besteht aus zwei Teilen: etwas tun und etwas behaupten. Der erste Teil gelingt generierten Tests fast immer. Der zweite ist die Frage. Ein Test ohne echte Zusicherung prüft nichts — er stellt nur fest, dass der Code nicht abstürzt. Und ein Test, dessen Erwartungswerte aus der Implementierung abgeleitet wurden, prüft sich selbst.

9:14 Beides ist grün, beides erhöht die Abdeckungszahl, und beides schützt Sie bei der Migration kein bisschen. Fünf Zeilen, und der Test ist grün. Sehen Sie sich die Zusicherung an: Es wird geprüft, dass das Ergebnis nicht leer ist. Bei einer Methode, die niemals leer zurückgibt, ist das eine Aussage über nichts. Der Test läuft, er zählt für die Abdeckung, und er würde auch dann grün bleiben, wenn die Buchung mit völlig falscher Menge angelegt wird.

9:41 Solche Tests sind nicht nur nutzlos — sie sind schädlich, weil sie Sicherheit vorspiegeln und dauerhaft Laufzeit kosten. Der zweite Punkt ist der methodisch wichtigste: Erwartungswerte aus der Implementierung prüfen sich selbst. Das passiert ganz natürlich, wenn man einen Test nachträglich schreibt — man lässt den Code laufen, sieht das Ergebnis und trägt es ein.

10:03 Damit haben Sie festgehalten, was ist, aber nicht geprüft, was sein soll. Der dritte Punkt ist die gute Nachricht: Aussagekraft ist im Review schnell zu beurteilen, wenn man darauf achtet. Es dauert Sekunden, nicht Minuten. Man muss nur hinsehen. Der erste Punkt ist der, der in Statusberichten passiert: die Zahl der Tests als Fortschritt melden.

10:24 Das ist eine Kennzahl, die sich mühelos erzeugen lässt und nichts aussagt — und sobald sie berichtet wird, wird sie optimiert. Der letzte Punkt klingt nebensächlich und ist es nicht: Tests ohne fachlichen Namen. „testeBuchung" sagt niemandem, worum es ging. Wenn dieser Test in acht Monaten rot wird, steht jemand davor und muss aus dem Code rekonstruieren, was er eigentlich prüfen sollte.

10:48 Diese Aufgabe ist bewusst eine Ablehnungsübung. Lassen Sie Tests zu einer Lagerwerk-Klasse erzeugen — Sie werden einige bekommen — und verwerfen Sie mindestens einen als aussagelos. Wichtig ist die Begründung: Was genau fehlt diesem Test? Es geht nicht darum, streng zu sein. Es geht darum, dass Sie das Kriterium anwenden können, statt es nur zu kennen.

11:09 Behalten Sie die verworfenen Beispiele — sie sind gutes Material für die Diskussion im eigenen Team.

Vom Stacktrace zur Ursache

11:16 Zum Abschluss dieses Moduls arbeiten wir einen echten Fehler ab. Der eigentliche Lerninhalt ist dabei nicht der Fehler — den bauen wir absichtlich ein, und er ist nicht besonders raffiniert. Der Lerninhalt ist die Reihenfolge, in der wir vorgehen. Sie ist unbequem, sie fühlt sich beim ersten Mal wie ein Umweg an, und sie ist trotzdem zuverlässig der kürzere Weg.

11:37 Der übliche Ablauf lautet: Fehler sehen, Fehler an den Agenten geben, Fix bekommen, weitermachen. Das funktioniert oft und hat einen Preis — die Ursache bleibt ungeklärt. Der Fix behebt möglicherweise nur das Symptom, und der eigentliche Fehler wandert eine Ebene tiefer. Deshalb kehren wir die Reihenfolge um: erst Ursachenhypothesen, ausdrücklich ohne Änderung. Dann ein Test, der den Fehler zeigt. Und erst dann der Fix.

12:04 Das ist dieselbe Denkweise wie beim Plan aus Modul 6 — verstehen vor ändern. Fünf Schritte, und der Kern ist Schritt vier: der Regressionstest vor dem Fix. Die Fußzeile sagt, warum — ein Test, der nach dem Fix entsteht, prüft nur, dass der Fix da ist. Er beweist nicht, dass er den Fehler behebt, denn er hat den Fehler nie gesehen. Schritt drei ist der, den man auslassen möchte: die Hypothesen am Code prüfen.

12:29 Aber genau dort trennt sich die plausible Erklärung von der richtigen — und plausibel ist bei Sprachmodellen die Voreinstellung, nicht die Ausnahme. Der erste Punkt ist die nüchterne Erfahrung: Die erste Hypothese ist oft plausibel und trotzdem falsch. Das gilt für Menschen genauso, nur formulieren Sprachmodelle ihre erste Hypothese überzeugender, als sie gemeint ist.

12:52 Der dritte Punkt beschreibt, was die Trennung der Schritte verhindert: das Verschieben des Fehlers. Wenn Ursache und Behebung in einem Zug passieren, merken Sie nicht, ob Sie behoben oder verlagert haben. Und der letzte Punkt ist der bleibende Wert: Der Regressionstest ist danach dauerhaft im Projekt. Der zweite Punkt ist der, den ich am häufigsten sehe: Symptome behandeln, indem eine Prüfung entfernt wird. Der Test wirft eine Ausnahme, also fangen wir sie.

13:19 Die Zusicherung schlägt fehl, also lockern wir sie. Das ist immer die schnellste Lösung und praktisch immer die falsche. Der letzte Punkt ist eine Frage der Systematik: mehrere Hypothesen gleichzeitig ausprobieren. Wenn danach alles funktioniert, wissen Sie nicht, welche stimmte — und beim nächsten Auftreten fangen Sie wieder von vorn an.

13:39 Zusammengefasst: Absicherung wird fachlich bewertet, nicht in Prozent gezählt — die Frage nach fehlenden Fällen ist nützlicher als jede Abdeckungszahl. Charakterisierungstests halten Verhalten fest, bevor die Migration es ändert, und sie tragen einen Kommentar, damit später niemand sie missversteht. Das Netz entsteht entlang der Risikostellen aus dem Migrationsplan, nicht flächendeckend. Und bei Fehlern gilt: Hypothese, Test, dann Fix.

14:05 Im nächsten Modul verlassen wir den Code und sehen uns an, was in Ihrem Haus über den Einsatz entscheidet.

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