Testing und Test-driven Development

Software-Entwicklung im Team ist ein sehr dynamischer Prozess. Wenn mehrere Personen gleichzeitig an einem Projekt arbeiten, kann sich die Gestalt des Projekts bereits innerhalb eines Tages extrem verändern. In der Regel wird die zu erledigende Arbeit in sehr viele kleine Einheiten eingeteilt, welche dann von den Entwicklern abgearbeitet werden.

Nicht selten ist es dabei notwendig, beispielsweise Code zu ändern, der von einem anderen Team-Mitglied geschrieben wurde, weil dieser Code sehr alt ist oder aus einem anderen Grund “fremd” ist. Eine Gefahr dabei ist, dass man die Auswirkungen seiner Änderungen nicht immer komplett absehen kann. Es kann sein, dass Code beispielsweise noch an einer anderen, unerwarteten Stelle genutzt wird, welche die Änderungen “nicht verträgt”.

Dies ist nur einer der unzähligen Gründe, warum man in der Software-Entwicklung schon seit geraumer Zeit dazu übergegangen ist, für möglichst viele (optimalerweise alle) Funktionen einer Software automatisierbare Tests zu schreiben. Diese Tests dienen dazu, sicherzustellen, dass unter bestimmten, fest definierten Bedingungen, eine Funktion in einer Software immer das gleiche, korrekte Ergebnis zurück gibt.

Ein solcher Test in der Regel folgendermaßen aufgebaut: Er schafft zunächst die festgelegten Anfangsbedingungen, ruft anschließend die zu testende Funktion auf und überprüft dann, ob die Funktion korrekt arbeitet, indem er die definierten Zielkriterien verifiziert. Im einfachsten Fall wäre dies einfach der Rückgabewert einer Funktion, welcher mit einem “korrekten” Rückgabewert im Test verglichen wird. Sind die beiden Werte gleich und damit die Zielkriterien erfüllt, war der Test erfolgreich. Leider ist es oft so, dass Tests nicht alle “Möglichkeiten” abdecken oder zum Beispiel gar nicht oder nur sporadisch existieren. In einem solchen Fall ist ein Urteil, ob die Software richtig funktioniert, nicht abschließend möglich.

Daher wurde Ende der 90er Jahre die Methode der sogenannten “testgetriebenen Entwicklung” (TDD) entworfen. Die zugrunde liegende Idee dieser Methode ist, dass man als erstes den Test schreibt, der, wie zuvor beschrieben, bereits Anfangsbedingungen und Zielkriterien definiert. Dieser Test wird zunächst natürlich fehlschlagen, da die zu testende Funktion noch gar nicht geschrieben ist. Dies wird erst anschießend getan. Sobald der Test nicht mehr fehlschlägt, ist die Funktion korrekt. Diese Schritte werden für alle weiteren Programmteile wiederholt.

Ein Vorteil des dest-driven development liegt auf der Hand: man kann so eine quasi vollständige Testabdeckung erreichen. Zusätzlich ändert sich allerdings auch die Art, wie der Entwickler programmiert. Anstatt darüber nachzudenken, wie ein Problem gelöst wird, muss bei TDD darüber nachgedacht werden, welches Ergebnis erwartet wird.

Bezogen auf das eingangs genannte Beispiel eines Team-Projekts wäre es mit vorhandenen Tests für den Entwickler in kürzester Zeit möglich, zu überprüfen, ob die Änderungen am fremden Code irgendwelche Auswirkungen auf andere Teile des Programms haben. Etwaige auftretende Fehler können so bereits während der Entwicklung sofort gefunden und behoben werden.