Test Driven Development

Test Driven Development (deutsch: testgeleitete Entwicklung; kurz: TDD) ist ein Entwicklungs- und Designparadigma für Software, bei dem das Testen von Programmkomponenten dazu verwendet wird, den gesamten Prozess der Softwareentwicklung zu leiten. Test Driven Development ist eine Designstrategie, die das Testen vor dem Erstellen des Quellcodes ansiedelt und mit Bezug auf die Abläufe vorrangig behandelt. Das Ziel liegt darin, die Qualität der Software maßgeblich zu erhöhen und den Wartungsaufwand im Nachhinein zu verringern. TDD wird meist im Rahmen agiler Methoden und insbesondere beim Extreme Programming verwendet.[1] Weitere Bezeichnungen für TDD sind testgetriebene Softwareentwicklung, testgeleitete Programmierung oder Test First Design.

Allgemeine Informationen zum Thema

Developer Testing war bereits in den Anfängen der Softwareentwicklung präsent. Während unabhängige Tester Softwarelösungen prüfen sollten, waren die Entwickler damit befasst, den eigentlichen Code zu schreiben. Die Entwicklung und das Testen waren üblicherweise entkoppelt. Erst als Kent Beck den Aspekt des Testens in seinen Ausführungen zum Extreme Programming mehr und mehr betonte, wurde der Test-First-Ansatz einem breitem Publikum bekannt. Beck und seine Mitstreiter sagten zum Beispiel, dass sie gewöhnlich den Test zuerst schreiben und der Quellcode nach den Testfällen geschrieben und implementiert wird.[2] Durch die fortschreitende Entwicklung hin zu agilen Methoden, fand der Test-First-Ansatz auch Einzug in andere Programmierparadigmen und wird heutzutage teilweise als eigene Designstrategie betrachtet.

Im Gegensatz zum nachgeschalteten Testing, das bei herkömmlichen Paradigmen wie dem Wasserfallmodell eingesetzt wird, sind die Testfälle im TDD der Ausgangspunkt für das iterative, sich wiederholende Vorgehen: Zunächst werden Testfälle bestimmt und realisiert. Diese Tests schlagen häufig fehl. Anschließend wird genauso so viel Code verfasst, wie es für das Bestehen des Tests notwendig ist. Diese Codebestandteile werden dann refaktorisiert; das heißt, dass der Quellcode unter Beibehaltung von Funktionen sukzessiv erweitert oder neu strukturiert wird. Dies erfolgt zyklisch, bis alle Anforderungen an die Software erfüllt werden und der Code in das Produktivsystem übertragen werden kann.

Funktionsweise

Test Driven Development läuft inkrementell ab: Die Software wird Schritt für Schritt erweitert, nachdem die ersten Testfälle geschrieben wurden. Bei jedem Schritt wird die Software mit teilweise minimalen Funktionen angereichert und wieder getestet. Jeder fehlerhafte Test zieht das Verfassen von Quellcode nach sich; jeder bestandene Test erweitert den Funktionsumfang oder stellt die Funktionalität der Software sicher. Einzelne Testfälle, auch Unittests genannt, nehmen in der Regel nur wenig Zeit in Anspruch, sodass der Fortschritt bei der Softwareentwicklung unmittelbar sichtbar wird.

Einige Entwickler schreiben eine Zeile Code für das Testing und danach eine Zeile Code für den Releasekandidaten. Dieses Herunterbrechen auf kleine Bestandteile der Software führt zu einem Zyklus, der die täglichen Abläufe strukturiert. Exemplarisch wird dieses Vorgehen in den drei Gesetzen des Test Driven Development:[3]

  • Schreibe einen Test, bevor du Code für das Produktivsystem verfasst.
  • Schreibe nur so viel Code für den Test, wie du für das Nichtbestehen des Tests benötigst (oder für das fehlgeschlagene Kompilieren)
  • Schreibe nur so viel Code, wie es für den aktuellen Testfall und dessen Bestehen hinreichend ist.

Entwickler, die diese Regeln befolgen, dürften Zyklen verwenden, die nicht mehr als 30 Sekunden lang sind. Die nächste Stufe bildet ein Zyklus, der auf Minuten bezogen ist und auch als Red-Green-Refactor bezeichnet wird.[4]

  • Test schreiben: Test schlägt fehl und wird rot markiert.
  • Produktivcode schreiben und in das Produktivsystem integrieren: Test wird bestanden und wird grün markiert.
  • Refactoring: Der Code wird Schritt für Schritt erweitert, ergänzt und neu strukturiert. Entsprechende Testfälle und die zugehörigen Codebestandteile werden geschrieben. Sie durchlaufen den Zyklus erneut, bis die Software aus Entwicklersicht einfach, elegant und verständlich ist. Jede nicht getestete Codezeile kann beim Refactoring zu Problemen führen, da es hier in erster Linie um die Struktur des Codes geht und nicht um die Funktionalität der Software, die durch den Test-First-Ansatz gewährleistet wird.

Daneben gibt es weitere Zyklen, die sich auf die Evolution des Entwicklungsprozesses beziehen. Der sogenannte Specific-Generic-Cycle und der Primary Cycle sind zu erwähnen. Der erste Zyklus soll sicherstellen, dass einzelne Module in ihrer Gesamtheit das Ziel der Software erreichen. Der zweite Zyklus macht Grenzen deutlich, die durch die Architektur und die vorher bestimmten Regeln gegeben sind. Eine klare Systemarchitektur und das Ineinandergreifen aller Module und Komponenten sind hier das Ziel.[5]

Vorteile/Nachteile

Der Ansatz des Test Driven Development hat gegenüber herkömmlichen Softwareentwicklungs-Methoden einige Vorteile.

  • Das Resultat des TDD ist Software auf qualitativ hochwertigem Niveau.
  • TDD sorgt für Software, die weniger wartungsintensiv und fehleranfällig ist.
  • Die Fehleranalyse und eventuelle Wartungsarbeiten sind einfacher und schneller.
  • Sowohl der Code als auch die Systemarchitektur sind sauber strukturiert und klar verständlich.
  • Redundanzen und nicht benötigte Codebestandteile werden effektiv vermieden.

Bedeutung für die Programmierung

Vor dem Kontext agiler Methoden in der Softwareentwicklung bildet die testgeleitete Entwicklung einen generellen Designansatz und kein Testing-Szenario. Die Tatsache, dass zuerst getestet wird beziehungsweise Testfälle geschrieben werden, führt dazu, dass das Testing die Triebfeder dieses Paradigmas ist. Manche Entwickler würden keine Zeile Quellcode schreiben, bevor nicht ein Testfall für die Codezeile vorliegt. Auf diese Weise wird nicht nur der Umfang des Codes reduziert, sondern auch die Effektivität des gesamten Projektes sichergestellt – inklusive kürzerer Veröffentlichungszyklen. Die Tests sorgen für einen Fokus auf die Ziele der Software und deren Funktionalität. Zudem ist es leichter, weitere Funktionen hinzuzufügen und die Software zu erweitern – selbst für Entwickler, die nicht am Projekt beteiligt waren. Zwar kann die testgetriebene Programmierung Entwickler mit sehr hohen Fachkenntnissen und viel Erfahrung erfordern, die Resultate sprechen jedoch auch für sich – wartungsfreie Software ist zum einen kein Kostenfaktor, der nach dem Release zum Tragen kommen könnte. Zum anderen sorgt der Ansatz für einbahnfrei funktionierende Software, die beim Endnutzer gerne angewendet wird, weil sie keine Fehler aufweist.

Einzelnachweise

  1. TestDrivenDevelopment martinfowler.com. Abgerufen am 11.02.2016
  2. Tdd guide.agilealliance.org. Abgerufen am 11.02.2016
  3. The Three Laws of Test-Driven Development programmer.97things.oreilly.com. Abgerufen am 11.02.2016
  4. The Cycles of TDD blog.cleancoder.com. Abgerufen am 11.02.2016
  5. The Clean Architecture blog.8thlight.com. Abgerufen am 11.02.2016

Weblinks