Start / Seminare / Jakarta EE modernisieren
Modul
Migration durch Tests absichern
4 Kapitel in diesem Modul-Video · Laufzeit
Transkript
Der gesprochene Text dieses Moduls zum Mitlesen, Überfliegen und Durchsuchen. Ein Klick auf einen Zeitstempel springt an die Stelle im Video.
Migration durch Tests absichern
0:00 Der dritte Tag beginnt mit dem Thema, das über Erfolg oder Scheitern einer Migration entscheidet: den Tests. Und mit einem Satz, der zunächst provoziert — bei einer Migration ist ein Test, der grün wird, weil er angepasst wurde, schlimmer als gar kein Test. Denn er suggeriert Sicherheit, die es nicht gibt. Wir sehen uns an, wie man vorhandenes Verhalten festschreibt, bevor man es anfasst, welche Testarten die neue Laufzeit anbietet, und wie man Bestand und Neubau gegeneinander prüft, solange beide laufen.
Migration durch Tests absichern
0:29 Der dritte Tag ist der Tag der Absicherung und des Betriebs. Wir sichern zuerst das Verhalten durch Tests ab, bringen den Dienst dann auf die Plattform, machen ihn beobachtbar, entscheiden zwischen JVM und nativem Betrieb, planen die schrittweise Ablösung des Bestands — und sehen uns zum Schluss an, was Werkzeuge und KI bei alldem leisten können und was nicht.
Verhalten festschreiben
0:49 Fangen wir mit der ungewöhnlichsten Testart an. Sie prüft nicht, ob etwas richtig ist — sie hält fest, wie es ist. Sie prüft nicht, ob etwas richtig ist — sie hält fest, wie es ist. Das fühlt sich falsch an und ist bei einer Migration genau richtig. Ein Characterization Test hält das heutige Verhalten fest, ohne es zu bewerten.
1:10 Er dokumentiert auch Eigenheiten, die niemand mehr erklären kann — die Rundung auf zwei Nachkommastellen an genau dieser Stelle, die Sonderbehandlung für Zähler ohne Ablesetermin. Für Entwicklerinnen und Entwickler fühlt sich das falsch an, weil man Merkwürdiges lieber korrigieren möchte. Aber bei einer Migration sind genau diese Eigenheiten das Gefährlichste: Irgendwo im Betrieb verlässt sich jemand darauf. Und Sie erfahren das erst, wenn es weg ist.
1:35 Diese Reihenfolge ist der ganze Trick — und sie ist unumkehrbar. Verhalten aufzeichnen, Test schreiben, migrieren, Test erneut ausführen. Wer erst migriert und danach Tests schreibt, hat kein Netz, sondern nur eine Bestätigung des Ergebnisses. Denn woher wollen Sie dann wissen, was vorher galt? Der Aufwand für Schritt eins und zwei erscheint im Projektplan als Verzögerung, und er wird deshalb oft gestrichen. Er ist aber keine Verzögerung, sondern eine Versicherung.
2:03 Und ihr Preis fällt genau dann an, wenn man sie nicht abgeschlossen hat. Hier eine Einordnung, die in Projektberichten selten steht: Eine hohe Abdeckung sagt nichts darüber, ob das Geschäft abgesichert ist. Sie können achtzig Prozent erreichen, indem Sie Hilfsklassen testen, und trotzdem keine einzige Aussage über die Tarifrechnung machen.
2:24 Punkt drei benennt die Verwechslung dahinter: Abgedeckt heißt ausgeführt, nicht geprüft. Ein Test, der eine Methode aufruft und nichts behauptet, zählt in der Statistik mit. Deshalb Punkt vier: Die Risikoliste aus Modul zwei bestimmt, wo Tests entstehen — nicht eine Prozentzahl in einem Bericht. Die Logik dieser Tabelle steht in der dritten Spalte, und sie ist bewusst gegenläufig zur zweiten.
2:48 Die Tarifrechnung hat niedrige Abdeckung und hohen Testbedarf — wegen der Geldwirkung. Die Stammdatenpflege hat hohe Abdeckung und niedrigen Bedarf; dort wurde in der Vergangenheit getestet, weil es leicht war. Genau diese Umkehrung ist der Punkt: Testarbeit gehört dorthin, wo Fehler weh tun, nicht dorthin, wo Tests einfach zu schreiben sind.
3:08 Und der Berichtsexport in der letzten Zeile ist der typische Übersehene — extern genutzt, kaum getestet, und niemand denkt an ihn. Punkt eins ist der Kernfehler bei Characterization Tests: Der Test schreibt das gewünschte Verhalten fest statt des vorhandenen. Das passiert nicht aus Schlamperei, sondern aus Fachkenntnis — man sieht die Merkwürdigkeit und schreibt auf, wie es eigentlich sein müsste.
3:31 Punkt zwei nennt die drei Klassiker, an denen es dann hängt: Rundungen und Zeitzonen. Punkt drei ist der Zeitfehler: Tests entstehen nach dem Umbau und beweisen nichts mehr. Und Punkt vier ist das Steuerungsproblem: Eine Prozentzahl als Prüfmaß führt zu Tests, die die Zahl erhöhen, nicht zu Tests, die Risiken decken.
Komponenten- und Integrationstests
3:50 Sehen wir uns an, welche Möglichkeiten die neue Laufzeit bietet. Und die erste ist bemerkenswert: Die Anwendung startet im Test wirklich. Die erste Möglichkeit ist bemerkenswert: Die Anwendung startet im Test wirklich, und die Tests können ihre Beans direkt injizieren. Mit der Annotation QuarkusTest startet die Anwendung einmal je Testklasse, und die Tests sind selbst CDI-Beans — Sie können also Beans injizieren und direkt prüfen.
4:16 Mit QuarkusIntegrationTest wird stattdessen das gebaute Artefakt als eigener Prozess gestartet. Der Unterschied ist wichtiger, als er klingt: Im ersten Fall testen Sie den Code, im zweiten das, was Sie ausliefern. Für eine Migration brauchen Sie beides — die schnelle Rückmeldung während der Arbeit und die Prüfung des Artefakts, bevor es in den Cluster geht.
4:37 Worauf es hier ankommt: Dieser Test spricht über HTTP mit der laufenden Anwendung — er prüft also den kompletten Weg inklusive Serialisierung, Fehlerabbildung und Statuscode. Genau das brauchen wir für den Vergleich aus Modul acht. Und wie die Fußzeile sagt: Die Testadresse wird automatisch gesetzt, der Testport liegt standardmäßig auf einem eigenen Port.
4:57 Sie müssen also nichts konfigurieren und riskieren keinen Konflikt mit einer laufenden Entwicklungsinstanz. Solche Kleinigkeiten entscheiden darüber, ob Tests im Alltag tatsächlich geschrieben werden. Die Logik dieser Tabelle: vier Mittel für vier verschiedene Fragen. Am wichtigsten für Migrationen ist die dritte Zeile — TestTransaction rollt Änderungen nach dem Test zurück und hält die Testdatenbank sauber.
5:21 Das ist der Unterschied zwischen einer Testsammlung, die auch beim zwanzigsten Lauf funktioniert, und einer, die nach drei Läufen an Datenmüll erstickt. Und beachten Sie die letzte Zeile mitsamt Einschränkung: Mocks nur dort, wo echte Infrastruktur fehlt. Die Fußzeile ergänzt eine praktische Regel: Integrationstests und normale Tests laufen nicht gleichzeitig, sie gehören in verschiedene Phasen.
5:44 Der letzte Punkt ist der entscheidende für dieses Seminar: Ein Mock friert eine Annahme ein, die bei der Migration gerade fraglich ist. Sie mocken die Datenbank, weil Sie wissen, wie sie sich verhält — aber genau das wollten Sie ja prüfen. Punkt eins nennt die konkreten Beispiele: Sperren und Sortierfolgen bildet kein Mock ab, und genau daran hängen Vergleichstests.
6:04 Punkt drei nimmt den üblichen Einwand vorweg: Die Entwicklungs-Infrastruktur startet die nötigen Container automatisch, es ist also kein Aufwand mehr, echte Systeme im Test zu verwenden. Punkt eins ist der, der Testsammlungen unbrauchbar macht: gemeinsame Datenbank, Tests stören sich gegenseitig — und zwar abhängig von der Reihenfolge, also sporadisch.
6:24 Punkt zwei ist die Ausprägung dessen, worüber wir gerade gesprochen haben: Es wird gemockt, was gerade geprüft werden müsste. Punkt drei ist praktisch: Integrationstests laufen in der Standardphase nicht mit und bleiben deshalb unbemerkt liegen — bis jemand merkt, dass sie seit Wochen rot sind. Und Punkt vier ist der Klassiker: Testdaten hängen am Datum und scheitern zum Monatswechsel. Bei einer Abrechnungsanwendung passiert das garantiert.
Alt gegen neu prüfen
6:50 Jetzt zur Disziplin, die es nur bei Migrationen gibt: Zwei Systeme, dieselbe Frage — und ein Vergleich, der belastbar sein muss. Zwei Systeme, dieselbe Frage — und ein Vergleich, der belastbar sein muss, weil an ihm die Freigabe hängt. Zwei Testarten mit unterschiedlichen Aufgaben. Ein Vergleichstest schickt dieselbe Eingabe an Bestand und Neubau und stellt die Antworten gegenüber.
7:15 Ein Contract Test prüft dagegen, ob beide Seiten dieselbe Vereinbarung einhalten — jede für sich, ohne dass beide laufen müssen. Der Vergleichstest ist das Werkzeug der Übergangszeit: aufwendig, aber unbestechlich. Der Contract Test ist das Werkzeug für danach: leichter zu betreiben, dafür nur so gut wie die Vereinbarung, die er prüft. Zusammen decken sie den Übergang ab.
7:38 Diese Gegenüberstellung hilft bei der Frage, wann Sie welche Prüfung brauchen. Der Vergleichstest findet stille Abweichungen — also genau die Sorte Unterschied, die niemand vereinbart hat und die trotzdem jemand nutzt. Dafür braucht er beide Systeme, und das geht nur während der Koexistenz. Der Contract Test läuft je Seite allein und findet Vertragsbrüche früh, auch noch Jahre später im Build.
8:00 Die praktische Empfehlung: Während der Migration den Vergleichstest, und was er an Erwartungen zutage fördert, wandert in Contract Tests, die dauerhaft bleiben. Ein Ausblick auf Modul sechzehn. Reflection und dynamisches Laden verhalten sich in nativen Abbildern anders, und Ressourcen müssen ausdrücklich aufgenommen werden.
8:19 Der springende Punkt ist Punkt drei: Fehler zeigen sich erst zur Laufzeit des nativen Prozesses — nicht beim Build, nicht in den normalen Tests. Sie bauen also erfolgreich ein Artefakt, das beim ersten echten Aufruf scheitert. Deshalb Punkt vier: Mindestens ein Integrationstest muss gegen das native Artefakt laufen. Wenn Sie nativ ernsthaft erwägen, gehört dieser Test von Anfang an in die Pipeline.
8:43 Der rote Faden: gleiche Eingaben, gleicher Datenstand, aufzeichnen, vergleichen, wiederholbar machen. Schritt eins nennt einen wichtigen Zusatz — Eingaben aus dem Produktivverkehr auswählen und anonymisieren. Echte Eingaben sind unschlagbar, weil sie Fälle enthalten, die sich niemand ausdenkt; anonymisiert müssen sie trotzdem sein.
9:03 Schritt vier enthält die Disziplin: Abweichungen als Befund erfassen, nicht sofort angleichen. Und Schritt fünf ist der, der über den Wert entscheidet — wie die Fußzeile sagt, altert ein Vergleich, der nur einmal von Hand lief, innerhalb weniger Tage. Punkt eins entwertet jeden Vergleich: unterschiedliche Datenstände. Dann ist jede Abweichung erklärbar, und damit ist keine mehr aussagekräftig.
9:27 Punkt zwei ist der, bei dem es rechtlich unangenehm wird: Produktivdaten ohne Anonymisierung in der Testumgebung — bei einer Anwendung mit Kundendaten wie Zählwerk ein echtes Problem, nicht nur ein formales. Punkt drei ist die verbreitete Abkürzung: Nur Statuscodes vergleichen, nicht die Inhalte. Und Punkt vier ist der kulturelle Fehler: Ein Befund wird stillschweigend angeglichen — dann fehlt die Spur, und dieselbe Frage kommt drei Module später wieder.
Übung
9:54 In der Übung sichern Sie die Tarifrechnung ab — das Modul mit der Geldwirkung, das wir in Modul sieben bewusst nicht als Piloten gewählt haben. Die Tarifrechnung ist das Modul mit der Geldwirkung, das wir in Modul sieben bewusst nicht als Piloten gewählt haben. Abgesichert werden muss es trotzdem. Sie schreiben Characterization Tests für die Tarifrechnung, bevor der Code angefasst wird.
10:16 Das Lernziel ist, bestehendes Verhalten so festzuschreiben, dass jede spätere Abweichung als Befund sichtbar wird — nicht als Diskussion, sondern als roter Test. Erfolgreich sind Sie, wenn die Tests gegen den Bestand grün laufen, gegen den Neubau ohne jede Anpassung, und jede Abweichung mit Ursache in der Befundliste steht.
10:34 Und der Hinweis ist die eigentliche Regel dieser Übung: Die Tests werden vor dem Umbau geschrieben und danach nicht mehr verändert. Fünf Schritte, und Schritt zwei ist der methodisch wichtigste: Die erwarteten Ergebnisse werden aus dem laufenden Bestand aufgezeichnet, nicht aus der Fachdokumentation abgeleitet. Denn die Dokumentation beschreibt die Absicht; der Bestand ist die Wirklichkeit, an die sich alle gewöhnt haben.
10:58 Und die Fußzeile nimmt Ihnen Suchzeit ab: Rundung, Zeitzone und Sortierung sind die drei häufigsten Ursachen für Abweichungen, in dieser Reihenfolge. Wenn ein Vergleichstest rot wird, prüfen Sie diese drei zuerst — in den meisten Fällen sind Sie damit schon fertig. Punkt eins ist die Todsünde dieser Übung: Ein Test wird angepasst, weil der Neubau ein anderes Ergebnis liefert.
11:20 Damit haben Sie das Netz weggenommen, das Sie gerade gespannt hatten. Punkt zwei ist die typische Lücke: Die Fälle decken nur den Standardtarif ab — und die Fehler stecken in den Sonderfällen. Punkt drei haben wir gerade besprochen. Und Punkt vier nennt die konkreten Grenzfälle für Zählwerk: Monatswechsel und Zählertausch.
11:38 Beides sind Situationen, in denen zwei Zeiträume aufeinandertreffen — und genau dort entscheidet sich, ob eine Rechnung stimmt.
Lieber mit Trainer? Dieses Modul ist Teil unserer Team-Schulungen — mit Übungen, Ihrem eigenen Code und Fragen, die ein Video nicht beantwortet. Mehr erfahren →