Was ist Test Driven Development?

Test-Driven-Development

Test-Driven-Development (TDD, Testgetriebene Entwicklung) für qualitativ hochwertigen Code

Test-Driven-Development (TDD) ist in den letzten Jahren zunehmend beliebter geworden. Viele Programmierer haben diese Technik ausprobiert, sind jedoch daran gescheitert und kamen daraufhin zu dem Schluss, dass TDD nicht den Aufwand wert ist, den es erfordert. Einige Programmierer denken, dass es sich in der Theorie um eine gute Praxis handelt, aber dass es nie genug Zeit gibt, TDD wirklich zu nutzen. Und andere denken, dass es im Grunde genommen Zeitverschwendung ist.
Trotzdem ist das Potential enorm, wir räumen mit den Missverständnissen auf.

Wenn auch Du so denkst, verstehst Du vielleicht nicht, was TDD wirklich ist. In diesem Artikel werden wir die Grundlagen des Test Driven Development zeigen und dabei gängige Missverständnisse über die TDD-Technik ansprechen.

Definition Test-Driven-Development?

Test-Driven-Development ist ein evolutionärer Entwicklungsansatz. Bei dieser Methode definierst Du zunächst einen Test und schreibst dann Code, um diesen Test zu absolvieren. Das Hauptziel von TDD liegt in der Spezifikation und nicht in der Validierung. Mit anderen Worten, Test Driven Development ist eine Möglichkeit, die Anforderungen oder Dein Design zu durchdenken, bevor Du den Funktionscode schreibst. Somit ist TDD sowohl eine wichtige agile Anforderung als auch eine agile Designtechnik. Test-Driven-Development als eine Programmiertechnik hat das Ziel, sauberen Code zu schreiben, der funktioniert.

Wie funktioniert testgetriebene Entwicklung im Vergleich zu anderen Entwicklungsmethoden?

Nehmen wir an, dass Du ein Webentwickler bist. Du hast gerade eine kleine Funktion abgeschlossen. Hältst Du es für ausreichend, diese Funktion allein durch manuelle Interaktion mit dem Browser zu testen? Es reicht nicht aus, sich nur auf Tests zu verlassen, die von Entwicklern manuell durchgeführt werden. Leider bedeutet dies, dass ein Teil des Codes nicht gut genug ist.

Beim Test-Driven-Development gibt es drei Regeln:

  • Du darfst keinen Produktionscode schreiben, es sei denn, er soll einen fehlerhaften Komponententest bestehen.
  • Es ist Dir nicht erlaubt, mehr von einem Komponententest zu schreiben, als ausreicht, um einen Fehler zu machen. Kompilierungsfehler sind Fehler.
  • Es ist Dir nicht gestattet, mehr Produktionscode zu schreiben, als notwendig, um den einen fehlgeschlagenen Komponententest zu bestehen.

Diese Regeln sind einfach, aber viele Programmierer verletzen oft eine oder mehrere von ihnen. Kannst du ein kleines Projekt schreiben, das sich strikt an diese Regeln hält? Diese Regeln definieren die Mechanik von TDD, aber sie sind definitiv nicht alles, was man wissen muss. Oft wird der Prozess der Verwendung von Test-Driven-Development auch als Rot/Grün/Refaktor-Zyklus beschrieben.

Rote Phase

In der roten Phase musst Du einen Test über ein Verhalten schreiben, das Du danach implementieren willst. Hier kommt es häufig zu einem Missverständnis: “Zuerst schreibe ich eine Klasse und eine Methode (aber keine Implementierung), dann schreibe ich einen Test, um diese Klassenmethode zu testen”. Das ist falsch.

In der roten Phase verhältst Du Dich wie ein anspruchsvoller Benutzer, der den Code, der gerade geschrieben wird, auf die einfachste Weise verwenden möchte. Du musst einen Test schreiben, der ein Stück Code verwendet, als ob er bereits implementiert wäre. Vergiss die Implementierung! Wenn Du in dieser Phase darüber nachdenkst, wie Du den Seriencode schreiben willst, machst Du es falsch!

In dieser Phase konzentrierst Du Dich vielmehr darauf, eine saubere Oberfläche für zukünftige Benutzer zu schreiben. Dies ist die Phase, in der Du festlegst, wie Dein Code von den Kunden verwendet wird.

Diese erste Regel ist die wichtigste und es ist die Regel, die TDD von den weit verbreiteten klassischen, regelmäßigen Tests unterscheidet. Du schreibst erst einen Test, damit Du dann Produktionscode schreiben kannst. Du schreibst keinen Test, um Deinen Code zu testen.

In dieser Phase musst Du Entscheidungen darüber treffen, wie der Code verwendet wird. Du stützt Dich dabei auf das, was Du im Moment wirklich brauchst, und nicht auf das, was Deiner Meinung nach gebraucht werden könnte.

Hier kommt ein weiterer Fehler: Schreibe nicht einen Haufen Funktionen/Klassen, von denen Du denkst, dass sie benötigt werden könnten. Konzentriere Dich auf das Feature, das Du implementierst, und auf das, was wirklich benötigt wird. Etwas zu schreiben, was die Funktion nicht erfordert, ist Over-Engineering.

Grüne Phase

Dies ist in der Regel die einfachste Phase, da Du in dieser Phase (Produktions-)Code schreibst.

Hier kommt ein weiterer großer Fehler: Anstatt genug Code zu schreiben, um den roten Test zu bestehen, schreibst Du alle Algorithmen. Während Du dies tust, denkst Du wahrscheinlich darüber nach, was die performanteste Implementierung ist. Auf keinen Fall!

In dieser Phase musst Du Dich wie ein Programmierer verhalten, der eine einfache Aufgabe hat: Schreibe eine unkomplizierte Lösung, die den Test besteht. In dieser Phase darfst Du gegen Best Practices verstoßen und sogar Code duplizieren.

Die testgetriebene Entwicklung bietet zwei weitere Möglichkeiten: eine Aufgabenliste und die Refaktorphase.

Die Refaktorphase wird zur Bereinigung des Codes verwendet. Die Aufgabenliste dient dazu, die Schritte aufzuschreiben, die erforderlich sind, um die von Dir implementierte Funktion abzuschließen. Sie enthält auch Zweifel oder Probleme, die Du während des Prozesses entdeckst. Diese Aufgabenliste ändert sich während der Programmierung und ist idealerweise am Ende der Arbeit leer.

Refaktorphase

In der Refaktorphase darfst den Code ändern, damit er besser wird. Was “besser” bedeutet, liegt bei Dir. Aber es gibt etwas Notwendiges: Du musst die Code-Duplizierung entfernen.
In dieser Phase spielst Du die Rolle eines wählerischen Programmierers, der den Code reparieren/refaktorieren möchte, um ihn auf ein professionelles Niveau zu bringen. In der roten Phase zeigst Du den Benutzern Deine Fähigkeiten. Aber in der Refaktorphase zeigst Du Deine Fähigkeiten den Programmierern, die Deine Implementierung lesen werden.

Vorteile- und Nachteile von Test-Driven-Development

Viele Programmierer beklagen den Zeitaufwand für das Test-Driven-Development. Was eigentlich viel Zeit erfordert, ist das Erlernen/Meistern von TDD sowie das Verstehen, wie man eine Testumgebung einrichtet und nutzt. Wenn Du mit den Testwerkzeugen und der TDD-Technik vertraut bist, braucht es eigentlich nicht enorm viel mehr Zeit, als klassische Entwicklungsmethoden. Im Gegenteil, es hilft, ein Projekt so einfach wie möglich zu halten und spart so tendentiell sogar Zeit.

Wie kann ich Test-Driven-Development beim Entwickeln nutzen?

Um Test-Driven-Development beim Entwickeln zu nutzen musst Du Dich an das oben vorgestellte Schema halten. Dann musst Du mindestens so viele Tests erstellen, wie nötig sind, um den gesamten Produktionscode zu schreiben. Sind die Tests bestanden, ist das Refactoring viel einfacher und sicherer für den zu testenden Code.
Test-Driven-Development hilft bei der agilen Programmierung, aber es ist definitiv kein Ersatz für die Analyse-/Designphase.

Fazit

Test-driven Development ist eine Entwicklungstechnik, bei der Du zuerst einen Test schreiben musst, bevor Du neuen Funktionscode schreiben kannst. TDD wird von Softwareentwicklern für die Entwicklung von Anwendungsquellcode und für die Datenbankentwicklung eingesetzt. Test-Driven-Development sollte als Ergänzung zu Agile Model Driven Development betrachtet werden. Beide können und sollten gemeinsam genutzt werden. Test-Driven-Development ersetzt nicht das traditionelle Testen, sondern definiert einen bewährten Weg, um einen effektiven Komponententest zu gewährleisten. Ein Nebeneffekt dabei ist, dass die resultierenden Tests Arbeitsbeispiele für den Aufruf des Codes sind und somit eine Arbeitsspezifikation für den Code liefern.

Rückmeldungen