7.2. Checkerberry db

Universelle Werkzeuge zeichnen sich dadurch aus, dass sie hilfreich in vielen Umgebungen eingesetzt werden können. Als Nachteil dieser Flexibilität stellt sich dann die Frage: Wie setze ich das Werkzeug in der aktuellen Umgebung am besten ein? Es gibt eine Reihe von Empfehlungen, die sich aus den Erfahrungen der letzten Jahre ergeben haben. Ein Teil dieser Empfehlungen kommt bereits aus dem DbUnit-Projekt [DbUnit Best Practices, 2010], wobei wir die Gelegenheit nutzen, sie hier noch einmal aufzugreifen und zu erläutern.

7.2.1. Good setup don't need cleanup

Fangen wir also gleich mit dem Klassiker an: Good setup don’t need cleanup [DbUnit Best Practices, 2010]. Hinter dieser griffigen Phrase verbirgt sich die Idee, dass Tests nach ihrer Ausführung nicht für das Aufräumen verantwortlich sind. Stattdessen ist jeder Test in der Setup-Phase dafür verantwortlich, alle benötigen Rahmenbedingungen herzustellen. In der Setup-Phase wird somit implizit für den zuvor ausgeführten Test aufgeräumt.

Das klingt erst einmal sinnvoll und logisch. Allerdings sollte man etwas tiefer einsteigen, um die verschiedenen Facetten dieser Regel zu verstehen.

Innerhalb von Unit-Tests wird die Setup-Phase genutzt, um die Rahmenbedingungen des Tests herzustellen. Danach wird der Test durchgeführt, bevor in der Teardown-Phase alle Ressourcen wieder freigegeben werden. Die Grundidee der Teardown-Phase bestand darin, dass sich das System nach dem Aufräumen in dem gleichen Zustand wie vor der Setup-Phase befinden sollte.

In der Praxis stellten sich dann jedoch einige Entwickler die Frage: Warum Aufräumen, wenn jeder Test ohnehin sein benötigtes Umfeld in der Setup-Phase wieder herstellt?

Es gibt viele Situationen, in denen ein Test Aufräumarbeiten leisten muss. Jeder Test muss nach seiner Ausführung dafür sorgen, dass die im Test erzeugten Objekte wieder freigegeben werden. Dies ist insbesondere im JUnit-Umfeld wichtig, da anderenfalls der Speicher unnötig verschwendet wird. Bei großen JUnit-Test-Suites kommt es in diesen Situationen regelmäßig zu OutOfMemory -Fehlern. Des Weiteren sollte jeder Test Änderungen rückgängig machen, die nur diesen Test betreffen. Ersetzt ein Test beispielsweise einen speziellen Service in der allgemeinen Umgebung durch eine eigene Implementierung, so muss dies nach der Testdurchführung wieder korrigiert werden. Es ist nicht pragmatisch, wenn hunderte Tests einen Service initialisieren müssen, nur weil ein einzelner Test eine andere Ausprägung des Services benötigt. Stellen Sie sich den Aufwand vor, wenn alle Tests die Besonderheiten einzelner Tests berücksichtigen müssten.

Auf der anderen Seite ist das Aufräumen der Datenbank nach der Testdurchführung überflüssig. Wenn ein Test die Datenbank benötigt, muss er in der Setup-Phase den gewünschten Zustand herstellen. Es wäre daher sinnlos, in der Teardown-Phase die Datenbank erst in den einen und in der Setup-Phase dann in einen anderen Zustand zu versetzen. Das kostet unnötig Zeit. Des Weiteren vereinfacht das unaufgeräumte Hinterlassen der Datenbank die Fehleranalyse. Führt man einen einzelnen fehlerhaften Test aus, so bleibt nach der Testdurchführung der letzte Zustand der Datenbank erhalten und kann somit direkt für die Analyse verwendet werden.