Test-Driven-Development (TTD) ist eine agile Methode, die aufgrund der steigenden Komplexität von Computerprogrammen immer beliebter wird. Als Technik gehört sie unter anderem zum Extreme Programming (XP), das sich durch stetige Reviews, Tests, Design und Redesign auszeichnet.
TTD sorgt durch fortlaufende Testfälle dafür, dass das Design einer Software gut durchdacht ist, bevor der Funktionscode geschrieben wird. Dadurch lässt sich sowohl der Wartungsaufwand reduzieren, als auch die Qualität der Software selbst steigern.
Die Tests, die eingesetzt werden, unterscheiden sich in Zweck und Umfang. Der Modul- oder Unit-Test sind besonders einfach gestaltet, komplexer sind Integrations- und Funktionstests, die nicht nur einzelne Komponenten, sondern die Gesamtfunktionalität der Software überprüfen.
Was sind die Grundlagen von Test-Driven-Development?
Testmethoden, welche die Qualität einer Software überprüfen, gab es schon zu Beginn der Softwareentwicklung. Anfänglich kontrollierten unabhängige Tester im Rahmen eines Qualitätsmanagements Computerprogramme auf ihre Funktionsfähigkeit. Softwareentwicklung und Testverfahren wurden zu dieser Zeit noch als unabhängige Prozesse betrachtet. Der Aufwand für Tests war dabei relativ hoch.
Der US-amerikanische Softwareentwickler, Begründer des Extreme Programming und Erstunterzeichner des Agile Manifesto Kent Beck rief daraufhin den Test-First-Ansatz ins Leben. Der bisherige Ablauf wurde hierbei einfach umgekehrt: Bevor die Entwickler den Quellcode verfassen, lassen sie Tests durchlaufen. Die Testfälle werden sodann verwendet, um den bestmöglichen Code zu schreiben und zu implementieren. Diese Methode kann als Vorstufe der TTD betrachtet werden.
Wie funktioniert Test-Driven-Development im Detail?
Anders als zum Beispiel beim Wasserfallmodell verlaufen die Prozesse beim TTD in einem Zyklus. Als erstes werden Testfälle bestimmt, die oftmals fehlschlagen. In einem zweiten Schritt verfassen die Entwickler nur so viel Code, wie für das Bestehen des Tests nötig ist. Daraufhin werden die Komponenten refaktorisiert, das heißt: der Quellcode wird so lange erweitert und wenn nötig umstrukturiert, bis der Test nicht mehr als fehlerhaft angezeigt wird. Er wird erst dann ins Produktivsystem übertragen, wenn alle Anforderungen an die Software erfüllt sind. So wird die Software schrittweise mit neuen Funktionen angereichert. Test-Driven-Development wird deshalb auch zu den inkrementellen Vorgehensmodellen gezählt. Die Technik setzt zudem ein Codeverständnis voraus und erfordert eine längere Einarbeitungszeit.
Der Zyklus, dem Programmierer im TTD nach Kent Beck folgen, wird auch Red-Green-Refactor-Zyklus genannt:
1. Red: Der Entwickler versetzt sich in die Rolle des Nutzers. In der Regel möchte dieser den Code auf eine einfache Weise verwenden. Es wird ein Test geschrieben, der Komponenten erhält, die noch nicht implementiert wurden. Der Entwickler muss sich dabei fragen, welche Elemente für die Funktionsfähigkeit des Codes wirklich notwendig sind.
2. Green: Schlägt der Test fehl und wird der Code rot markiert, muss der Programmierer eine Lösung finden. Generell soll nur so wenig Code wie möglich geschrieben werden. Dieser wird sodann in den Produktivcode integriert, bis der Test grün markiert wird.
3. Refactor: Hier wird der Produktivcode in seiner Struktur perfektioniert, das heißt: er wird so lange ergänzt und umstrukturiert, bis er verständlich und redundanzfrei ist.
Diese drei Schritte werden solange wiederholt, bis der Code die gewünschte Funktionalität liefert. Die behandelte programmtechnische Einheit (Unit) wird dann als vorerst abgeschlossen angesehen.
Welche Werkzeuge (Tools) werden beim Test-Driven-Development genutzt?
Die einzelnen Testfälle durchlaufen den Zyklus üblicherweise nicht länger als ein paar Sekunden oder Minuten, sodass die Resultate schnell im Produktivcode sichtbar sind. Typischerweise verwenden Entwickler dafür ein Tool zur Build-Automatisierung wie Gitlab-Ci, Github Actions oder Google Cloud Build. Bei Ruby stehen Bibliotheken wie rspec und minitest zur Verfügung; bei Elixir liefert ExUnit ein umfangreiches Framework für TDD.