Hinweis! Eine aktuelle Version des Abschnittes gibt es im Buch „Java ist auch eine Insel. Einführung, Ausbildung, Praxis“, dem 1. Inselbuch. (War für den 2. Band vorgesehen, musste wegen der Fülle des 2. Buchs kurzerhand in den 1. Band geschoben werden. Sorry für Irritationen!)
1.1 Softwaretests
Um möglichst viel Vertrauen in die eigene Codebasis zu bekommen, bieten sich Softwaretests an. Tests sind kleine Programme, die ohne Benutzerkontrolle automatisch über die Quellcodebasis laufen und anhand von Regeln zeigen, dass gewünschte Teile sich so verhalten wie gewünscht. (Die Abwesenheit von Fehlern kann eine Software natürlich nicht zeigen, aber immer zeigt ein Testfall, dass das Programm die Vorgaben aus der Spezifikation erfüllt.)
Obwohl Softwaretests extrem wichtig sind, sind sie unter Softwareentwicklern nicht unbedingt populär. Das liegt unter anderem daran, dass sie natürlich etwas Zeit kosten, die neben der tatsächlichen Entwicklung aufgewendet werden muss. Wenn dann die eigentliche Software geändert wird, müssen auch die Testfälle oftmals mit angefasst werden, so dass es gleich zwei Baustellen gibt. Und da Entwickler eigentlich immer gestern das Feature fertig stellen sollten, fallen die Testes gerne unter den Tisch. Ein weiterer Grund ist, dass einige Entwickler sich für unfehlbare Codierungsgötter halten, die jeden Programmcode (nach ein paar Stunden debuggen) für absolut korrekt, performant und wohl duftend halten.
Wie lässt sich diese skeptische Gruppe nun überzeugen, doch Tests zu schreiben? Ein großer Vorteil von automatisierten Tests ist die Eigenschaft, dass bei großen Änderungen der Quellcodebasis (Refactoring) die Testfälle automatisch sagen, ob alles korrekt verändert wurde. Denn wenn nach dem Refactoring, etwa einer Performance-Optimierung, die Tests einen Fehler melden, ist wohl etwas kaputt-optimiert worden. Da Software einer permanenten Änderung unterliegt und nie fertig ist, sollte das Argument eigentlich schon ausreichen, denn wenn eine Software eine gewisse Größe erreicht hat, ist nicht absehbar, welche Auswirklungen Änderungen an der Quellcodebasis nach sich ziehen. Dazu kommt ein weiterer Grund, sich mit Tests zu beschäftigen. Es ist der positive Nebeneffekt, dass die erzeugte Software vom Design deutlich besser ist, denn testbare Software zu schreiben ist knifflig, führt aber fast zwangsläufig zum besseren Design. Und ein besseres Design ist immer erstrebenswert, denn das erhöht die Verständlichkeit und erleichtert die spätere Anpassung der Software.
1.1.1 Vorgehen bei Schreiben von Testfällen
Die Fokussierung bei Softwaretests liegt auf zwei Attributen: automatisch und wiederholbar. Dazu ist eine Bibliothek nötig, die zwei Dinge unterstützen muss.
· Testfälle sehen immer gleich aus und bestehen aus drei Schritten. Zunächst wird ein Szenario aufgebaut, dann die zu testende Methode oder Methodenkombination aufgerufen und zum Schluss mit der spezifischen API vom Testframework geschaut, ob das ausgeführte Programm genau das gewünschte Verhalten gebracht hat. Das Übernehmen eine Art „stimmt-es-dass“-Methoden, die den gewünschten Zustand mit dem tatsächlichen Abgleichen und beim Konflikt eine Ausnahme auslösen.
· Das Testframework muss die Tests laufen lassen und im Fehlerfall eine Meldung geben; der Teil nennt sich Test-Runner.
Wir werden uns im Folgenden auf sogenannte Unit-Tests beschränken. Das sind Tests, die einzelne Bausteine (engl. units) testen. Daneben gibt es andere Tests, wie Lasttests, Performance-Tests oder Integrationstests, die aber im Folgenden keine große Rolle spielen.