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

Modul

Testdaten und unterschiedliche Szenarien

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.

Testdaten und unterschiedliche Szenarien

0:00 In diesem Modul geht es um ein Problem, das jede wachsende Testsuite bekommt. Eine Regel ist getestet, dann fällt jemandem ein Sonderfall ein, dann noch einer — und irgendwann stehen zwanzig fast identische Testmethoden untereinander, die sich nur in den Zahlen unterscheiden. Das sieht nach guter Abdeckung aus und ist in Wahrheit zwanzigmal dieselbe Wartungsaufgabe.

0:20 Wir sehen uns an, wie aus solchen Wiederholungen Datensätze werden, wie man die interessanten Fälle systematisch findet statt sie zu raten, und wie datengetriebene Tests übersichtlich bleiben.

Testdaten und unterschiedliche Szenarien

0:31 Wir sind im vierten Modul des ersten Tages. Nachdem die Tests jetzt lesbar sind, geht es um ihre Menge: parametrisierte Tests, dann die Systematik hinter den Grenzfällen, und zum Schluss die Struktur, die datengetriebene Tests wartbar hält.

Parametrisierte Tests

0:45 Fangen wir mit dem Werkzeug an. Eine Regel, viele Daten — und ein Testbericht, in dem man die Daten auch wiederfindet. Ein parametrisierter Test führt dieselbe Methode mehrfach mit unterschiedlichen Argumenten aus. Denken Sie an eine Prüfschablone in der Fertigung: Ein Werkzeug, viele Werkstücke. Woher die Argumente kommen, entscheiden Sie über die Quelle — einfache Werte, eine kleine Tabelle im Test, eine Datei oder eine Methode, die Objekte liefert.

1:14 Neu und praktisch: Seit JUnit 6 lässt sich auch eine ganze Klasse parametrisieren. Dann laufen alle Tests dieser Klasse einmal je Argumentkonstellation. Das ist genau dann Gold wert, wenn eine Konfiguration mehrere Regeln gleichzeitig beeinflusst. Der entscheidende Teil steht nicht im Testrumpf, sondern in der ersten Zeile: der Name mit Platzhaltern.

1:35 Ohne ihn zeigt der Bericht vier gleichnamige Läufe mit einem Index — und beim roten Lauf wissen Sie nicht, welcher Fall gebrochen ist. Mit Platzhaltern lesen Sie im Bericht: zehn Kisten je siebzehn Euro zehn. Das ist der Unterschied zwischen einer Zahl und einer Aussage. Zweiter Punkt, der leicht untergeht: Der Preis wird als BigDecimal geführt und mit einem Wertvergleich geprüft.

1:57 Mit Fließkommazahlen würde dieser Test irgendwann aus Rundungsgründen scheitern. Die Logik dieser Tabelle ist eine Steigerung von einfach nach mächtig. Ganz oben einzelne Werte, dann kleine Tabellen direkt im Test — dort, wo man die Fälle beim Lesen sofort sieht. Weiter unten wird es dynamischer: Dateien für größere Datenmengen, Methoden für alles, was berechnet werden muss oder ein Objekt ist.

2:20 Der Hinweis in der Fußzeile ist mir wichtig: Objekte gehören in eine Methodenquelle. Wer sie stattdessen als Text in eine Tabelle schreibt und einen Konverter davorsetzt, baut eine zweite, unsichtbare Schicht, in der die Hälfte erraten wird. Diese drei Helfer lösen dasselbe Problem aus verschiedenen Richtungen: Die Parameterliste wird zu lang. Ein Konverter macht aus einer Textspalte einen fachlichen Typ.

2:45 Ein Aggregator bündelt mehrere Spalten zu einem Objekt — aus fünf Parametern wird eine Bestellung. Und der Zugriff auf alle Argumente hilft dort, wo die Signatur sonst unleserlich würde. Ohne diese Mittel passiert regelmäßig dasselbe: Die Parameterliste wächst auf sieben Argumente, alle vom Typ String oder int, und niemand weiß mehr, welches an welcher Stelle steht.

3:06 Spätestens dann kostet der Test mehr, als er einbringt. Der erste Punkt ist der Rundungsfehler, den ich eben erwähnt habe — Beträge gehören nicht in double. Der zweite ist der fehlende Testname; er kostet Sie bei jedem roten Lauf Zeit. Der dritte ist ein handfestes Detail: Kommas im Wert müssen in einer kommagetrennten Quelle in Anführungszeichen stehen, sonst rutschen die Spalten.

3:29 Und der vierte ist ein Wachstumsproblem — die Datenmenge steigt, bis der Test zehn Sekunden braucht und niemand ihn mehr lokal startet. Wenn das passiert, fehlt meist die Systematik, um die es im nächsten Kapitel geht.

Grenzfälle systematisch abdecken

3:42 Und damit zur eigentlich spannenden Frage: Welche Werte gehören überhaupt in so eine Tabelle? Raten hilft hier erstaunlich wenig. Grenzwertanalyse ist eine alte Technik und immer noch die wirksamste. Der Gedanke: Werte, die sich gleich verhalten, bilden eine Klasse — und aus jeder Klasse genügt ein Vertreter. Interessant wird es genau an den Übergängen. Deshalb prüfen Sie je Grenze zwei Werte: den letzten ungültigen und den ersten gültigen.

4:09 Dazu kommen null und leer, die eigene Klassen bilden und in der Praxis am häufigsten vergessen werden. JUnit liefert dafür fertige Quellen mit, sodass Sie diese beiden Fälle nicht von Hand aufschreiben müssen. Diese Kette zeigt, warum die Mitte einer Klasse uninteressant ist. Links der ungültige Bereich, rechts der gültige — und dazwischen zwei Werte, an denen sich alles entscheidet.

4:32 Fehler entstehen fast nie im Inneren einer Klasse. Sie entstehen an der Grenze, und zwar meistens durch ein Vergleichszeichen: größer statt größer-gleich. Genau dieser eine Tippfehler wird von einem Test mit fünfzig Kisten niemals gefunden — von einem Testpaar mit neun und zehn Kisten dagegen sofort. Deshalb lohnt es sich, die Grenzen aufzuschreiben, bevor man Testdaten wählt.

4:55 Das ist die praktische Konsequenz und zugleich eine Beruhigung: Sie brauchen nicht mehr Daten, Sie brauchen die richtigen. Werte innerhalb einer Klasse verhalten sich gleich, einer genügt. An jeder Grenze braucht es zwei. Aus fünfzig geratenen Fällen werden so acht begründete — und die laufen schneller und sagen mehr. Der letzte Punkt ist zugleich ein nützliches Werkzeug für Gespräche mit dem Fachbereich: Ein Wert, den Sie keiner Klasse zuordnen können, ist meistens eine ungeklärte fachliche Frage.

5:23 Solche Fragen findet man selten im Code, aber regelmäßig beim Aufschreiben der Klassen. Hier wird es konkret. Vier Regeln, und je Regel genau zwei Werte — der letzte, bei dem sie noch nicht greift, und der erste, bei dem sie greift. Achten Sie auf die letzte Zeile: Auch Zeiträume haben Grenzen, und Datumsgrenzen sind besonders fehleranfällig, weil dort Zeitzonen und Tagesanfänge mitspielen.

5:47 Aus dieser kleinen Tabelle werden acht Testfälle. Acht, nicht fünfzig. Und diese acht decken jede der vier Regeln vollständig ab, weil alles dazwischen per Definition gleich behandelt wird. Das ist der ganze Trick an der Sache. Der erste Punkt ist der klassische Anfängerfehler und passiert auch Erfahrenen: getestet wird die Mitte, wo garantiert nichts passiert.

6:09 Der zweite ist die Lücke, die ich am häufigsten sehe — null und leer gelten als Sonderfall und tauchen in keinem Test auf, obwohl genau dort die meisten Ausnahmen entstehen. Der dritte ist eine Verwechslung: Wiederholte Tests führen denselben Fall mehrfach aus, sie liefern keine neuen Daten. Und der vierte ist eine verpasste Chance: Die Grenzen stehen im Test, aber nicht in der fachlichen Beschreibung — dabei sind sie dort genauso wertvoll.

Datengetriebene Tests organisieren

6:33 Bleibt die Frage der Ordnung. Wenn viele Fälle zusammenkommen, entscheidet die Struktur darüber, ob der Testbericht noch lesbar ist. Verschachtelte Klassen gruppieren Tests nach ihrer Vorbedingung und erben deren Aufbau — der äußere Aufbau gilt, der innere kommt dazu. Im Bericht entsteht dadurch eine Gliederung statt einer flachen Liste. Dynamische Tests sind das andere Extrem: Sie entstehen erst zur Laufzeit aus einer Fabrikmethode.

6:59 Das ist genau dann richtig, wenn die Fälle beim Schreiben des Tests noch gar nicht bekannt sind — etwa weil sie aus einer Datei oder aus der Datenbank kommen. Mächtig, aber auch schwerer zu lesen, deshalb die zweite Wahl. Lesen Sie diesen Block einmal laut: Wenn der Korb leer ist — ist der Preis null. Wenn der Korb leer ist — schlägt die Bestellung fehl. Genau so erscheint es im Testbericht.

7:22 Die verschachtelte Klasse trägt die Vorbedingung, die Methoden tragen die Erwartung, und der gemeinsame Aufbau steht einmal statt zweimal. Der praktische Nutzen zeigt sich, wenn eine dritte und vierte Erwartung dazukommen: Sie ergänzen eine Zeile und nicht wieder einen ganzen Aufbau. Wichtig ist nur, dass die Gruppierung wirklich einer Vorbedingung folgt und nicht einer Klassenstruktur.

7:45 Die mittlere Spalte ist die Entscheidungsspalte. Stehen die Fälle beim Schreiben fest, nehmen Sie eine parametrisierte Methode oder — wenn eine ganze Klasse betroffen ist — eine parametrisierte Klasse. Stehen sie erst zur Laufzeit fest, bleibt die Testfabrik. Der Hinweis darunter ist ernst gemeint: Dynamische Tests sind die letzte Wahl.

8:04 Sie sind schwerer zu lesen, ihre Namen entstehen erst zur Laufzeit, und im Bericht sehen sie oft alle gleich aus. Wer sie einsetzt, sollte besonders sorgfältig für sprechende Namen sorgen — sonst verliert der Bericht seinen Wert. Diese Trennung ist derselbe Gedanke wie überall in der Softwareentwicklung, nur auf Tests angewandt.

8:24 Sind Daten und Logik getrennt, können Sie einen Fall ergänzen, ohne den Test zu lesen. Fachliche Beispiele lassen sich direkt übernehmen — und zwar in der Form, in der sie aus dem Fachbereich kommen. Eine Datei mit Fällen ist im Review lesbar, eine verschachtelte Schleife nicht. Und der letzte Punkt ist eine gute Faustregel: Wächst die Datei über hundert Zeilen, fehlt fast immer eine Äquivalenzklasse.

8:47 Dann hilft nicht mehr Struktur, sondern das Kapitel davor. Der erste Punkt ist Schubladendenken im Wortsinn: Die verschachtelte Klasse wird zur Ablage für alles, was sonst nirgends passt. Der zweite betrifft dynamische Tests — sie erzeugen Fälle, deren Namen im Bericht identisch aussehen, und dann ist der Bericht wertlos.

9:05 Der dritte ist ein Handwerksfehler mit Folgen: Testdaten im Hauptquellbaum werden mit ausgeliefert. Und der vierte ist der inhaltlich wichtigste: Wer nach der Klassenstruktur des Codes gruppiert statt nach Vorbedingungen, bekommt eine Gliederung, die beim nächsten Umbau nicht mehr stimmt.

Übung

9:22 Jetzt bringen wir die drei Kapitel zusammen — an den Preisregeln von Krautgut, die genau so unübersichtlich sind, wie echte Preisregeln nun einmal sind. Drei Regeln gelten: der Staffelpreis ab zehn Kisten, der Aktionsrabatt auf Honig und die Versandkostenfreigrenze bei fünfundzwanzig Euro. Ihre Aufgabe ist, diese drei mit höchstens zwei Testmethoden abzudecken. Das klingt streng und ist Absicht — es zwingt Sie, die Fälle zu ordnen statt sie zu sammeln.

9:48 Zwei weitere Kriterien: Jeder Fall soll im Bericht mit seinen Werten erscheinen, und jede Grenze soll mit beiden Nachbarwerten geprüft sein. Wenn Sie am Ende deutlich mehr als acht Fälle haben, lohnt ein zweiter Blick auf die Äquivalenzklassen. Der rote Faden ist eine Bewegung von der Fachlichkeit zur Technik. Erst zerlegen Sie die Regeln in Klassen und notieren die Grenzen — auf Papier, nicht im Editor.

10:12 Dann werden daraus zwei Werte je Grenze und eine kompakte Tabelle im Test. Schritt drei ist die Lesbarkeit: der Testname mit Platzhaltern. Schritt vier ist der Übergang von Zahlen zu Objekten, und damit von einer technischen zu einer fachlichen Beschreibung. Und Schritt fünf zeigt, wofür parametrisierte Klassen da sind: wenn alle drei Regeln gleichzeitig in verschiedenen Konstellationen gelten sollen.

10:36 Der erste Punkt entscheidet über die ganze Übung: Werden die Fälle geraten statt aus den Grenzen abgeleitet, haben Sie am Ende viele Fälle und wenig Aussage. Der zweite ist unser bekannter Rundungsfehler — Beträge als Fließkommazahl. Der dritte ist eine Vermischung, die den Bericht unbrauchbar macht: Aktionsrabatt und Freigrenze in einem Fall; bricht er, wissen Sie nicht, welche Regel schuld ist.

10:58 Und der vierte ist der Preis der Mächtigkeit — eine parametrisierte Klasse multipliziert die Läufe. Behalten Sie die Gesamtzahl im Auge, sonst wächst die Laufzeit unbemerkt.

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