Mittwoch, 23. Mai 2012


Artikel

April 2009 | Artikel

Aufklärung tut Not: Nee zu TDD?

(Link zum Artikel: http://www.entwickler.de/jaxenter//002215)

Perspektivenwechsel Teil 7

Text: Das Dr. Dommer Team: Henning Wolf und Johannes Link
  • Teilen
  • kommentieren
  • empfehlen
  • Bookmark and Share
In der Clique sprechen alle von TDD (Test-driven Development, also testgetriebener Entwicklung). Aber wer macht es wirklich? Viele sagen, dass es sich merkwürdig anfühlt, nicht nur beim ersten Mal. Wir fragen Dr. T. D. Dommer, einen Experten auf dem Gebiet, mit welchen Fragen und Sorgen ihn junge Entwickler und Entwicklerinnen häufig aufsuchen. Schließlich scheint die Theorie zu TDD noch ziemlich einfach, aber wie kann der Funke überspringen, der den Anfänger zum eleganten Könner macht?
Teil 1   Teil 2   

Claudius A. (25) aus Hildesheim fragt: Wie soll ich eigentlich etwas testen, das noch gar nicht existiert?

Dr. T. D. Dommer antwortet : Wir haben uns daran gewöhnt, Produktivcode zu schreiben, der vorher auch nicht existiert hat. Dabei denken wir uns im Voraus einen Zusammenhang, in dem dieser Produktivcode sinnvoll erscheint, und schreiben ihn einfach hin, lassen ihn gegebenenfalls vom Compiler überprüfen. Mit testgetriebener Entwicklung machen wir einen Teil dieses Denkprozesses explizit und denken den Produktivcode aus der Sicht seines ersten Benutzers: dem Test. Wir stellen uns also beim Testen einfach mal vor, welche Klassen und Methoden wir uns wünschen würden, um einen bestimmten Sachverhalt zu testen. Auch wenn es diese Klassen und Methoden noch gar nicht gibt. So entsteht der Test zuerst. Viele Entwicklungsumgebungen erlauben uns dann das automatische Erstellen von Klassen- und Methodenrümpfen, die wir dann „nur noch“ mit Leben füllen müssen. Dies beantwortet erst einmal die Mechanik, wie wir etwas testen können, das noch nicht existiert.

Meist interessiert aber auch die Frage: Warum sollte ich so vorgehen? Hier gibt es vor allem zwei große Vorteile hervorzuheben:

  1. Der entstehende Produktivcode wird strukturiert aus der Sicht eines Benutzers der entsprechenden Klassen und Methoden. Das führt zu besserem Design, als aus der Sicht einer einzelnen Datenstruktur heraus Methoden anzubieten. Es führt zuweilen sogar zu deutlich weniger Produktivcode, weil scheinbar notwendige Methoden (was man hinzufügen kann, muss man auch löschen können) vom Test gar nicht benötigt werden. Dann sollten sie auch noch nicht erstellt werden.
  2. Methodisch hat der Ansatz der testgetriebenen Entwicklung den Vorteil, dass nur getesteter und testbarer Code entsteht. Das systematische Testen nach der Erstellung des Produktivcodes hat nämlich zwei Nachteile: Zum einen wird es oft einfach weggelassen, weil es an Disziplin mangelt oder der (Zeit-)Druck zu hoch scheint. Zum anderen merkt man dann erst beim Testen, dass der Code schlecht testbar ist und aufwändig umgebaut werden müsste. Diesen Aufwand scheut man dann aber, obwohl es allgemein als anerkannt gilt, dass schlecht testbarer Code definitiv auch schlecht entworfener Code ist. Viele heutige Systeme sind over-designed und under-tested.

Domenikus B. (29) aus Dresden zweifelt: Muss ich wirklich so kleine Schritte machen? Ich fühle mich so gebremst...

Dr. T. D. Dommer erwidert: Eine wichtige Idee hinter testgetriebener Entwicklung ist, die vollständige Kontrolle über das Programmiergeschehen zu behalten: Als Entwickler sollte ich immer wissen, ob der nächste Testlauf fehlschlagen wird oder nicht, und was ich tun muss, um einen fehlschlagenden Test wieder „grün“ zu machen. Am besten lässt sich diese Idee durchhalten, wenn ich in ganz kleinen Schritten vorgehe. In einer Minute kann ich nur Chaos für eine Minute anrichten – und dementsprechend schnell auch wieder beseitigen.

Die meisten TDD-Anfänger tendieren dazu, ihre Schritte – oft gleichbedeutend mit der Größe und Komplexität des neuesten Testfalls – stetig zu vergrößern, um schneller zu werden. Dies ist auch o.k., wenn man die Schrittweite wieder entsprechend reduziert, sobald die Kontrolle verloren geht: wenn z. B. 10 Minuten statt geschätzter zwei vergehen, bevor man alle Tests am Laufen hat. So pendelt sich die optimale Schrittweite langsam ein; erfahrene TDDler berichten meist von Mikroiterationen zwischen 2 und 5 Minuten Länge. Die Gefahr für den Test-First-Neuling ist, dass er es nicht bemerkt, wie ihm langsam die Kontrolle entgleitet und wie das geordnete Vorgehen immer mehr zu einem Stochern im Code verkommt. (O-Ton: „Vielleicht läuft der Test, wenn ich hier '<=' statt '<' benutze“.) Erwischt man sich bei einem solchen Vielleicht-Gedanken, ist die Zeit für Schrittweitenkürzung gekommen. Mein Motto lautet daher: Hier ist kürzer auf jeden Fall besser!

Ein anderer Aspekt ist die gerade am Anfang subjektiv wahrgenommene Verlangsamung. Diese rührt daher, dass die Zeit für einen Design-Test-Code-Refactor-Zyklus tatsächlich länger ist, als wenn wir lediglich den im Kopf roh vorhandenen Code hinschreiben. Dass wir jedoch durch die höhere Kontrolle die Anzahl der Verbesserungsdurchgänge reduzieren, merkt man erst nach einiger Weile. TDD sollte uns tatsächlich schon von Beginn eines Projekts an schneller machen – sobald wir die Technik beherrschen – nicht erst mittelfristig durch niedrigere Fehlerraten.

Teil 1   Teil 2   

andere Artikel dieser Serie

Kommentare

Gravatar Alexander Elsholz 02.04.2009
um 13:44 Uhr
Hallo,

Bei den Vorteilen testgetriebener Entwicklung fehlt ein ganz wichtiger, für Entwickler oft entscheidener Faktor:
"erhöhte Entwicklungsgeschwindigkeit".
Entwickelt man testgetrieben hat man viel kürzere Feedbackschleifen. Anstatt die Anwendung im WorstCase:
- zu kompilieren
- ein Artefakt zu generieren
- zu deployen
- zu starten
- an die zu testende Funktion zu navigieren

um erst dann zu bemerken, das eine NullPoinerexception auftritt startet man in Bruchteilen einer Sekunde den UnittTest und hat (hoffentlich) nach ebensolanger Wartezeit auch die Antwort.

Dieses Argument führt, nach meiner Erfahrung zur höchste Akzeptanz bei Entwicklern.

mfg
Alexander Elsholz
#zitieren