Start

Schneller, bessere Software entwickelnTest Driven Development

Über Test-Driven-Design (TDD) wurde schon sehr viel geschrieben und dieser Artikel soll und kann keine Einführung in das Thema sein. Er soll vielmehr Entwickler dazu animieren, sich mit dem Thema auseinanderzusetzen. Ich beschreibe die Vorteile von TDD aus meiner persönlichen Entwicklungserfahrung und hoffe, dass es den einen oder anderen den entscheidenden Anstoß gibt, TDD einmal selbst auszuprobieren.

Der TDD Grundzyklus

Statt gleich die gewünschten Klassen zu implementieren, fängt man mit einem Test an. Dieser schlägt natürlich fehl, da es ja noch keinen Code gibt, der die eigentlich zu testende Funktion umsetzt. Im nächsten Schritt implementiert man den Code solange, bis der Test grünes Licht gibt.

An diesem Punkt hat man nun eine funktionierende Methode. Jetzt geht man hin und überlegt sich, wie man den Code noch ein bisschen schöner / sauberer machen kann. Anschließend prüft man den Test wieder. Diesen Zyklus wiederholt man solange, bis man zufrieden ist.

Der TDD Grundzyklus

Arten von Tests

Ich halte die Einteilung von Tests in die folgenden Kategorien für sinnvoll und ausreichend:

  • Unit Tests: Ein Unit Test testet

Frühes Testen vs. Spätes Testen

In den meisten meiner Projekte wurde eher spät mit dem Testen angefangen, also kurz vor dem offiziellen Release. Einfache Unit- und Integration-Tests wurden zwar früher entwickelt, aber die richtigen End-to-End-Tests und Acceptance-Tests kamen erst ganz spät. Und dann passiert praktisch immer das Gleiche: die Tests fördern Probleme zutage, an die bislang keiner gedacht hat. Wenn es ganz schlecht läuft, entdeckt man grundsätzliche Design-Probleme, die nicht mal eben schnell behoben werden können, sondern einen beträchtlichen Teil an Neuentwicklung benötigt!

Jetzt können zwei Dinge passieren:

  • Das Release wird verschoben und das Problem sauber behoben.
  • Es wird ein Work-around gefunden, der das Problem kaschiert, so dass das Release trotzdem stattfinden kann. Es wird beschlossen, bei nächster Gelegenheit das Problem sauer zu beheben.

In der Regel wird sich für Letzteres entschieden. Ob das Design-Problem in der Folge behoben wird, ist fraglich. Falls es nicht behoben wird, geht man eine technische Schuld ein. Meistens dauert es nicht lange, bis man genau wegen dieser technischen Schuld eine andere Funktion nicht sauber umsetzen kann und für diese ebenfalls eine weitere technische Schuld eingehen muss. Je mehr dieser Schulden gemacht werden, desto schwieriger wird es, zukünftig Funktionen sauber umzusetzen.

Durch TDD ist die Gefahr dieses Teufelskreises deutlich geringer. Im Idealfall baut man ganz früh schon End-to-End-Tests und Acceptance-Tests, damit grundsätzliche Probleme sofort sichtbar werden.

Das Problem dabei ist: nach außen sieht es am Anfang so aus, als würde das Projekt keine Fortschritte machen, weil nichts Sichtbares vorgewiesen werden kann. Es muss so viel eingerichtet, konfiguriert, gemockt usw. werden, dass Projektverantwortliche leicht nervös werden. Selten wird erkannt, dass durch das frühe Lösen dieser Probleme hinten raus sehr viel Zeit gewonnen wird. Das wird von Projektverantwortlichen leider nicht immer so gesehen; im Gegenteil: aus Erfahrung wissen sie, dass es kurz vor dem Release immer zu Chaos und Verzögerung kommt und sie denken, wenn sie jetzt schon am Anfang keinen Fortschritt sehen, wie soll es erst kurz vor dem Release werden?

Frühes Testen dreht aber diesen Spieß um und reduziert das Chaos am Ende deutlich spürbar. Das folgende Schaubild soll das illustrieren:

Früh testen vs. Spät testen

Ein weiterer häufig zu beobachtender Negativeffekt von spätem Testen ist: sobald man anfängt, einen Test zu entwickeln, stellt man fest, dass die Komponenten in der aktuell implementierten Form gar nicht testbar sind!

Es könnte zum Beispiel sein, dass die zu testenden Daten aufgrund des Zugriffslevel (protected / private) gar nicht zugreifbar sind. Das Design sieht es einfach nicht vor. Man sollte jetzt aber nicht die für den Test notwendigen private Properties einfach auf public umstellen, nur damit man testen kann. Bei einem solchen Fall merkt man, dass nicht von Anfang an ans Testen gedacht wurde. Hätte man TDD gemacht, wäre das sofort aufgefallen und man hätte gleich gemerkt, dass mit dem Design etwas nicht stimmt.

Fortsetzung folgt...

Firma

di - IT Consulting
Dirk Illenberger
Bismarckstr. 24
61169 Friedberg

© 2021 di - IT Consulting, Dirk Illenberger