Follow my new blog

Dienstag, 18. Dezember 2012

Die TDD Single Responsibility

Gerade wird wieder eine TDD Demo über Twitter herumgereicht. Corey Haines hat sich an die Kata Roman Numerals gemacht.

image

Mal abgesehen davon, dass TDD anscheinend ein unerschöpfliches Thema ist und die Katas auf die Dauer langweilig werden… Mir gefällt die Darstellung aus einem anderen Grunde nicht so gut.

Corey gibt sich Mühe. Alles läuft seinen kanonischen TDD Weg. Es könnte ein schönes Video sein. Wäre da nicht die ständige Überraschung.

Ja, es hört sich so an, als würde Corey in die Lösung des Problems “Übersetzung arabischer Zahlen in römische” stolpern. Er zaubert Testfälle aus dem Hut und erstaunt sich dann immer wieder selbst mit der Lösung.

Und ich meine hier wirklich die Lösung und nicht den Code.

Da scheint mir ein Grundproblem im Umgang mit TDD zu liegen. Das habe ich auch neulich auf den XPdays in Coding Dojos gesehen. Das Muster ist so:

  1. Es wird ein Problem vorgestellt.
  2. Es wird mit dem Codieren à la TDD begonnen.

Das Ergebnis? Regelmäßig kein Code, der die Aufgabe vollständig erfüllt [1].

Mit dieser Realität sollten wir nicht streiten, denke ich. So ist es einfach. Man bemüht sich redlich um die rechte TDD-Schrittfolge. Das kommt mir vor wie beim Tanzen. Alle starren gebannt auf ihre Füße und hoffen, niemanden anzurempeln. Nur leider geht dabei das große Ganze verloren. Beim Tanzen der Spaß an der Bewegung und am Miteinander. Und bei der Softwareentwicklung lauffähiger Code. Vor lauter TDD-Rhythmus und versuchtem Design funktioniert es nicht mal.

Wie frustrierend, wie tragisch. Kein Wunder, dass auch 2012 immer noch TDD hoch und runter evangelisiert werden muss.

Dabei scheint mir die Rettung der Situation einfach: mehr Systematik.

Ja, tut mir leid, dass ich mit so einem lästigen Wort komme. Das klingt nach Einschränkung, nach viel Aufwand ohne schnellen Nutzen… doch das Gegenteil ist der Fall. Systematik macht frei. Aus Komplexem macht sie Kompliziertes.

Fehlende Systematik überfrachtet TDD. TDD soll plötzlich die ganze Softwareentwicklung retten. Endlich wird das mit der Korrektheit besser. Und dann auch noch bessere Dokumentation durch TDD. Und außerdem höhere Evolvierbarkeit durch besseres Design (lies: bessere Strukturen). Vor allem aber nicht zu vergessen: eine Lösung stellt sich auch wie von selbst ein.

Kommt das niemandem merkwürdig vor? One size fits all?

Ich bin ein großer Freund der Prinzipien Single Responsibility (SRP) und Separation of Concerns (SoC). Danach scheint mir ein bisschen viel Last auf den Schultern von TDD zu liegen.

Das ist es auch, was mich an Coreys Demonstration wieder stört. Er steht dabei nur als einer von vielen, die TDD zeigen. Die Vermischung von Lösung und Design stößt mir auf. Sie ist es nämlich, die zu den erwähnten Misserfolgen in den Dojos führt.

TDD bedeutete zunächst Test-Driven Development. Da ging es also um eine bestimmte Art zu codieren. Red-green-refactor. Das hat vor allem zu hoher Testabdeckung geführt.

Dann wurde aus dem Development das Design: Test-Driven Design. Die Betonung wurde damit auf den Refactoring-Schritt gelegt. Zur hohen Testabdeckung sollte dann auch noch eine “gut” Codestruktur kommen.

Und heute? Mir scheint, dass es gar nicht mehr um TDD geht, sondern um TDPS: Test-Driven Problem Solving. Nicht nur sollen Tests zu einem Design führen – denn über das Design soll man ja vorher nicht nachdenken, es soll entstehen, in minimaler Form. Nein, jetzt sollen am besten die Tests auch noch die Lösung herbeiführen.

Wenn Sie sich nun fragen, was denn da der Unterschied sei, dann rühren Sie genau an dem Problem, das ich meine: Es wird kein Unterschied zwischen Lösung und Code gesehen. Oder vielleicht sollte ich sagen, zwischen Lösungsansatz und Code? Ist es dann deutlicher?

Hier zwei Beispiele für den Unterschied.

Als erstes eine Lösung für das Problem des Sortierens eines Feldes. Text und Bild beschreiben einen Ansatz, sie beschreiben ein Vorgehen, sie sagen, wie man das Ziel ganz grundsätzlich erreichen kann:

image

Und jetzt ein Design in F# für diesen Lösungsansatz:

image

Im Design, im Code finden sich natürlich die Aspekte und Schritte des Lösungsansatzes wieder. Aber der Code ist nicht der Lösungsansatz. Er implementiert ihn in einer bestimmten Programmiersprache mit bestimmten Sprach- und Plattformmitteln.

Als zweites ein Lösungsansatz für ein Problem im Compilerbau, die Erkennung von Bezeichnern. Hier ein Syntaxdiagramm dafür:

image

oder alternativ ein Deterministischer Endlicher Automat:

image

Dass es überhaupt eine Phase zur Erkennung von Bezeichnern gibt (lexikalische Analyse), ist ebenfalls Teil eines Lösungsansatzes:

image

Das konkrete Code-Design, die Implementierung des Lösungsansatzes, könnte dann so aussehen:

image

Lösungsansatz – oder auch Modell – und Code in einer bestimmten Struktur – nach TDD auch Design genannt –, sind einfach verschiedene Aspekte. In den TDD-Vorführung wie bei Corey und den TDD-Selbstversuchen in den Dojos werden die jedoch nicht sauber getrennt. Immer wieder wird gehofft, durch Red-Green-Refactor nicht nur ein evolvierbares Design herzustellen, sondern auch eine Lösung zu bekommen.

Das (!) halte ich für falsch. Erstens ganz praktisch aus der Beobachtung heraus, dass so selten lauffähiger Code entsteht, der die Aufgabe erfüllt. Zweitens eher theoretisch aus dem Gedanken heraus, dass wir Menschen damit schlicht unterfordert sind. Das über Jahrtausende geschliffene Werkzeug “Denken” wird nicht genutzt. Man hofft vielmehr, durch Mustererkennung beim Code, irgendwie zu einer Lösung zu kommen.

Das funktioniert manchmal tatsächlich, wenn man genau hinschaut. Die Kata Roman Numerals könnte dafür ein Fall sein. Nur ist nicht zu erwarten, dass das immer so geht. Auf den Quicksort Lösungsansatz kommt man nicht durch TDD, davon muss man einfach eine Vorstellung entwickeln – eben einen Lösungsansatz. Im Kopf. Durch Nachdenken.

Und wie sollte es dann anders aussehen mit TDD?

Systematischeres Vorgehen

Systematisierung, Entzerrung, Entlastung, Fokus finde ich wichtig. Aus meiner Sicht sollte das Vorgehen diese Schritte beinhalten:

  1. Problem vorstellen
  2. Lösungsansatz entwickeln
  3. Testfälle ermitteln und priorisieren
  4. Lösungsansatz mit TDD implementieren

Schritte 2. und 3. können dabei mehrfach durchlaufen werden. Und wenn sich bei 4. noch neue Erkenntnisse zum Lösungsansatz ergeben sollten, dann ist das auch ok. Aber 4. ohne explizites 2. und 3. zu beginnen, halte ich für eine Überlastung.

Damit wären Lösungsansatz und Design getrennt. Damit würde – da bin ich ganz sicher – die Erfolgsquote jedes Coding Dojos steigen. Und wenn nicht, dann würde man genau sehen, woran es liegt: Liegt es an mangelnden TDD-Fähigkeiten oder liegt es an mangelndem Problemverständnis und dadurch fehlender Lösungsphantasie?

Die Single Responsibility von TDD liegt für mich bei der Testabdeckung und bei einer hohen Strukturqualität im Kleinen [2].

Was jedoch da überhaupt in Code gegossen und strukturiert werden soll… das ergibt sich nicht durch TDD, sondern durch Nachdenken. Den Lösungsansatz zu finden und die Testfälle zu priorisieren, das ist nicht Teil von TDD – muss aber gezeigt werden. Denn wird es nicht gezeigt bzw. wie bei Corey mit dem TDD-Vorgehen vermischt, entsteht entweder eine Überlastung, die die Aufgabenerfüllung behindert. Oder es entstehen “Wunderlösungen”, über die man nur staunen, sie aber eher nicht nachvollziehen kann. Wer “Wunderlösungen” goutiert, der wird es schwer haben, selbst Lösungen für andere Probleme zu finden.

Fußnoten

[1] Damit will ich nicht sagen, dass es keine Teams gibt, die die Aufgaben schaffen. Aber das passiert eben nicht regelmäßig und systematisch. Ich erinnere mich lebhaft an ein Dojo auf den XPdays und an eines auf der DDC im letzten Jahr. 5-10 Teams gab es jeweils. Und keines hat funktionierenden Code für die Kata Roman Numerals bzw. die Kata Zeckendorf (Übersetzung einer ganzen Zahl in eine Zeckendorf-Sequenz) abgeliefert.

[2] Wobei sogar diese Strukturqualität im Kleinen nicht einfach so entsteht, wie ich an anderer Stelle schon ausgeführt habe. Dafür braucht es Refactoring-Kompetenz und –Willen. Die kommen nicht aus TDD. Dafür braucht es aus meiner Sicht noch Hilfestellung, die Refactorings näher legt. Dadurch kann sich ein TDD 2.0 auszeichnen. Aber dazu ein andermal mehr…

13 Kommentare:

Anonym hat gesagt…

Hallo Ralf,

da kann ich nur voll und ganz zustimmen. Persönlich baue ich für jedes einigermaßen nichttriviale Problem ersteinmal 1..n Prototypen. Auf Papier, manchmal im Kopf, oft als Code, selten jedoch testgetrieben. Und erst die finale Implementierung, ab und an auch ein letzter Prototyp sind dann tatsächlich testgetrieben entwickelt. Nach dem Design / Lösungsansatz, der sich aus den Prototypen ergeben hat...

Anonym hat gesagt…

Hi Ralf,
vielen Dank für deine Gedanken. Diese Tage habe ich noch mit Kollegen diskutiert und dabei die These aufgestellt "Die Fachleute können nicht spezifizieren, so dass das Problem u. ein ev. Lösungsansatz für andere Fachleute verständlich ist.". Das ist dann darin gegipfelt, das ich schon Bedarf nach einem Fach Spezifikationslehre sah. Ok, das ist scharf angespitzt, aber mir immer noch lieber, als der tägliche Pfusch.
Schöne Feiertage u. einen guten Rutsch.
Gruß
Andreas

Alex hat gesagt…

Danke für den interessanten Artikel, aber ich verstehe nicht so ganz wo das Problem liegt :/ Wieso ist es schlimm, wenn man über die Lösung "stolpert". Ist es nicht der Sinn der iterativen/agilen Entwicklungsmethoden, dass man nach und nach in kleinen Schritten zu einer Lösung kommt, statt vorher einen perfektes Design zurecht zu schustern, welches dann in der Realität kläglich versagt? Sicher TDD befreit natürlich nicht vom Entwurf, aber erlebt man beim Entwerfen und Modellieren nicht auch oft genung Überraschungen? ;)

#Spezifikationslehre: Ist das nicht genau das, was die geschätzten Business Analysts so tun? Die haben uns imho ja auch nicht sehr weit gebracht und richten mehr Schaden an, als sie Nutzen bringen.

Ralf Westphal - One Man Think Tank hat gesagt…

@Alex: Es geht nicht um einen perfekten Lösungsansatz. Durch die Implementation kann sich ein Lösungsansatz auch immer noch verändern.

Aber es geht mir darum, überhaupt einen Vorstellung von einer Lösung zu haben. Die fehlt oft. Es wird nach 2-3 Lesen einer Aufgabe losgelegt. Erstmal coden, dann mal sehen.

Und genau so sieht es bei Corey im Video aus. Da mag man sagen, das sei dem Videoformat geschuldet... Das sehe ich jedoch anders. Wer das Vorgehen nicht systematisch präsentiert, der hat keine Systematik - oder vermittelt zumindest keine. Sehr schade.

Wie gesagt: Roman Numerals ist trivial. Da mag es so gehen - wenn auch meine Erfahrung zeigt, dass es 90% der Teams eben nicht hinkriegen. Doch was ist mit etwas schwierigeren Aufgaben... Das Wurschteln nimmt da auch mit TDD kein Ende.

Unknown hat gesagt…

Ich sehe das ähnlich!
TDD verkommt eher zu einer Einladung, seinen Kopf komplett abzuschalten.

"Jetzt tun wir alle mal so, als ob wir nicht 1 und 1 zusammenzählen können und sehen, wie uns TDD zum gewünschten Ziel führt."

Ich weiß auch nicht, warum man sich neuerdings dümmer macht, als nötig.

Für mich ist immer noch die Essenz beim Programmieren die Problemlösung. Quasi das Schönste am Ganzen.

Ralf Westphal - One Man Think Tank hat gesagt…

@Christian: Schön gesagt: Die Problemlösung macht den Spaß aus, nicht die Codierung.

Oder die Codierung nur insofern, als dadurch die Lösung zum Leben erwacht und jmd nützt. Das ist auch nett.

Eigentlich ist das doch auch keine neue Erkenntnis. Codierung ist nötig und manchmal knifflig. Soooviele Technologien/APIs... Aber ich glaube nicht, dass es eine große Zahl Entwickler gibt, die es Klasse finden, sich darin aufzureiben.

Die Lösung finde ich also am besten selbst. Das Hirn soll ja auch mal zu etwas nützlich sein ;-) Und nur, wenn ich grad so gar keine Idee habe... dann exploriere ich mit Code. Aber ich benutze dann doch nicht TDD.

Insofern: Wer mit TDD arbeitet, der schreibt Produktionscode. Und wer Produktionscode schreibt, der hat die Lösung schon. Was er vielleicht noch nicht hat, ist das vollständige Design.

Bei TDD kann es also nur darum gehen, Strukturen bei Kenntnis der Lösung auszutreiben.

GeH hat gesagt…

Das ist doch Quatsch zu behaupten das TDD das Denken verbietet. Es ist nun leider so, dass eine neue Technik nur erlernt werden kann wenn man versucht die bereits angeeigneten Muster nicht anzuwenden. Deshalb wird in Dojos versucht ohne vorherige Design-Gespräche TDD zu praktizieren mit manchmal erstaunlichen Ergebnissen, jedoch auch vielen Misserfolgen.
TDD ist nicht nur ein Werkzeug sondern Werkzeug + Fähigkeit das Werkzeug zu benutzen. Diese Fähigkeit zu erlernen ist nicht einfach und dauert meiner Erfahrung nach 2 bis 6 Monate Praxis. Dazu sind Katas recht gut geeignet.
Mich würde mal interessieren wie viele der erfahrenen TDD'ler in Katas Misserfolge haben würden.
Grundsätzlich: TDD ist kein Ersatz für das Denken

Ralf Westphal - One Man Think Tank hat gesagt…

@GeH: Zu dem Satz "Nicht nur sollen Tests zu einem Design führen – denn über das Design soll man ja vorher nicht nachdenken, es soll entstehen, in minimaler Form." stehe ich.

Dass TDD das Denken verbietet, steht da nicht drin. Aber vorher, bevor man den ersten Test schreibt, soll man nicht über Design (!) nachdenken. D.h. Lösungsansatz und daraus resultierende Grobstukturen des Codes sind kein Thema für TDD.

Und wenn doch, dann zeige man mir 1. die einflussreiche Literatur, die das so sagt und vorführt, und 2. die Coding Dojos wo das so praktiziert wird. Dann nehme ich gern alles zurück und behaupte das Gegenteil.

Einstweilen bleibe ich bei der simplen Beobachtung auf Coding Dojos verschiedener Plattformen. Und die zeigt mir: Nachdenken über Lösungen und Design findet de facto nicht statt.

Aber wenn das so ist und man dann TDD übt, dann wird TDD nicht mit Nachdenken verknüpft. Es stellt sich dann ein Reflex ein, in dem Entwurf nicht vorkommt.

TDD in einer Weise zu üben, bei der man Wichtiges auslässt, weil das Neue so bunt schillert, halte ich für fahrlässig.

Außerdem sehe ich nicht, was an red+green+refactor monatelang zu üben wäre. Die Schrittfolge? Kaum.

Refactoring? Sicherlich. Aber das ist eine Disziplin, auf die TDD ja schon aufbaut. Die übt man nicht speziell durch TDD, sondern wendet sie dort an - wenn man sie denn beherrscht. (Ob das der Fall ist, steht auf einem ganz anderen Blatt. Auch da sieht es nicht rosig aus.)

Oder braucht es Monate, KISS zu üben? Oder der Einsatz von Mock-Frameworks?

Dass man TDD üben muss, steht außer Zweifel. Aber wir sollten die Kirche im Dorf lassen. TDD ist kein Hexenwerk. Und es geht auch nicht um Perfektion. Selbst Robert C. Martin wird bei mehrfachem Durchlaufen der selben Kata zu immer wieder neuen Lösungen kommen. Wann ist er (bzw. der Code) also perfekt? Nie.

Dass es viele erfahrene TDDler gibt, wage ich zu bezweifeln. Und damit meine ich Leute, die wirklich deliberate practice betreiben und nicht nur irgendwie mal nach test-first entwickeln.

Leider sehe ich in Dojos nie (!) erfahrene TDDler. Ich sehe viele total motivierte Entwickler. Ich sehe Überzeugte, die etwas weitergeben wollen. Und das ist ja auch wunderbar.

Aber eine Reflexion von TDD - und das gehört für mich zu Erfahrung dazu -, die sehe ich nie. Echt.

Ich habe noch nie eine Diskussion über TDD in einem Dojo gehört. Also ein Gespräch auf der Meta-Ebene, bei dem z.B. gefragt würde, wann man nicht nur durch den SUT API testen soll oder wie man die Reihenfolge der Testfälle am besten festlegt.

Es wird viel über KISS gestritten. Es wird lustig rotiert am Rechner. Es wird während des Codings in unterschiedliche Lösungsrichtungen gezogen. Es wird wenig über Refactoring gesprochen. (Wie denn auch bei den Miniproblemen?) That´s it.

Wenn also TDD kein Ersatz für´s Denken ist, dann sollte Denken mal stattfinden im Dojo. Einfach mal ausprobieren. Wie wäre das?

GeH hat gesagt…

@Ralf: Wenn man TDD auf red+green+refactor reduziert, dann meinen die meistten TDD nach ein paar Tagen zu beherrschen. Sie stellen dann fest, dass es ihnen nicht wirklich weiterhilft und entfernen TDD aus ihrem Werkzugkasten.

Für mich ist TDD aber viel mehr:
red: richtige Tests in der richtigen Reihenfolge
green: vernünftigen Code um das Problem zu lösen
refactor: der schwierigste Schritt der in jedem guten TDD Training intensiv geübt wird

Ich glaube nicht, dass wir ein TDD 2.0 brauchen. Deine vorgeschlagene Methode (DotnetPro) sollte meiner Ansicht nach anders genannt werden.

Übrigens: einen RPN-Rechner hat Brett Schuchert vorbildlich mit TDD implementiert (http://vimeo.com/album/205252)

Ralf Westphal - One Man Think Tank hat gesagt…

@GeH: Tut mir leid, dass wir unterschiedlicher Meinung sind.

Natürlich ist TDD unter den Phasen red+green+refactor genau das, was du beschreibst. Aber das wird eben nicht intensiv geübt. In keinem Dojo, das ich bisher gesehen habe. (Kurse besuche ich nicht, sondern gebe sie selbst ;-) Und da behandeln wir diese Punkte - allerdings etwas anders als üblich. Denn im Rahmen eines TDD Kurses, für den Firmen max. 2 Tage investieren, kann man nicht (!) all das intensiv üben. Das scheitert schon an der Infrastruktur, mit der Teilnehmer auf ihren Rechnern immer wieder Probleme haben.)

Außerdem halte ich eine Verquickung unter der Überschrift TDD für falsch und fahrlässig. Gerade Refactoring ist so eine eigenständige Disziplin, dass man sie nicht im Vorbeigehen mit durchnehmen kann.

TDD 2.0 ist deshalb nötig, um die Aspekte, die in TDD 1.0 von mir aus immer schon mitgedacht wurden, explizit zu machen. Nur so werden Entwickler verstehen, dass TDD eben nicht sooo einfach ist.

Das Beispiel von Schuchert ist für mich übrigens wieder mal eine Demonstration dessen, wie man es nicht tun sollte. Ganz grauslich.

Es fehlt jede Erklärung der Problemdomäne. Es wird überhaupt nicht sichtbar nachgedacht. Es gibt keine Testfälle mit Prioritäten. Und nach 1 Std ist noch kein Operator implementiert. Sorry, das ist für mich schon fast cargo cult.

Und nochmal: Refaktorisierung ist kein Selbstzweck. Wenn ich durch kurzes Überlegen langes Refactoring sparen kann, dann sollte ich das tun. Allemal, wenn das kurze Überlegen auch noch Ergebnisse liefert, die die Lösung besser kommunizierbar machen. Oder die Implementation besser skalieren lassen. Denn so wie Schuchert es tut, kann nur einer allein an einem Problem arbeiten. Nicht sehr ökonomisch.

GeH hat gesagt…

@Ralf: unterschiedlicher Meinung zu sein ist ok. Ich schätze Dich persönlich sehr, TDD habe ich aber doch lieber bei Uncle Bob gelernt.

Schuchert's Video finde ich faszinierend. Der Code der dabei entstanden ist entspricht so ziemlich meinen Vorstellungen von 'Clean Code'.

Ich kenne einige Trainer die für TDD Kurse etwa 2 Wochen empfehlen. Bei uns gab es auch nur einen 2 tägigen Kurs und danach hat keiner TDD praktiziert.

Ralf Westphal - One Man Think Tank hat gesagt…

@GeH: Schön, wenn Code irgendwann mal clean ist.

Doch das ist mir zu wenig. Denn wenn ich nur auf das Endergebnis schaue, weiß ich nicht, wieviel das gekostet hat. Softwareentwicklung ist ein Unternehmen, das ökonomisch sein muss. Jedenfalls das, was man tagsüber am Arbeitsplatz macht. Wie man daheim bei einem Open Source Projekt als Hobby vorgeht, ist egal.

Viele kleine und kleinste ökonomische Schritte (KISS) addieren sich jedoch nicht unbedingt zu einer insgesamt ökonomischen Lösung. Das sehe ich auch bei Schuchert so. Das 3.+4. Video zeigen zwar hübsch die Anwendung von Prinzip und Pattern - nur hätte Schuchert sich das von vornherein sparen können. Es ist ja nicht so, dass ihn Operatorvielfalt überrascht.

Insofern sage ich mal, seine Lösung mag am Ende clean sein - der Weg dahin jedoch ist unökonomisch.

Und agil ist sein Vorgehen schon gar nicht. Fast 1 Std hüsert er an irgendwelcher Infrastruktur herum, ohne auch nur einen Operator auf die Straße zu bekommen.

Woher hat er auch seinen API? Der entsteht im luftleeren Raum. Warum gibt es da eine Enter()-Methode? Was hat er im Kopf, das er da implementiert? Ohne eine Vorstellung im Vorhinein kann er keine Liste priorisierter Testfälle haben, die du ja auch wichtig findest.

Schuchert zeigt also aus meiner Sicht Fingerfertigkeit. Er zeigt, dass er ein Skript abarbeiten kann - denn das liegt garantiert neben ihm. Aber er zeigt kein realistisches TDD. Er zaubert. Doch dadurch lernt es niemand. Dasselbe gilt für Corey Haines Video, das ich schon mal zitiert habe. Das sind alles von mir aus tolle Zauberer.

Doch Zauberei ist zunächst mal nur Entertainment. Sie beeindruckt mich. Nach einer Vorstellung kann ich aber nicht selber zaubern.

Dass Entwickler die Videos faszinierend im Sinne von Entertainment finden, finde ich total verständlich. Alles geht Schritt für Schritt, es werden ein paar bekannte Vokabeln eingestreut, die ganze Zeit nur Code... da schlägt das Entwicklerherz höher.

Wenn dann aber ein Zuschauer vor eine solche Aufgabe gestellt würde, hätte er außer der Schrittfolge red+green+refactor wieder nichts gelernt.

Observational learning ist nicht schlecht. Nur sind wir alle nicht mehr 5 Jahre alt. Wir können auch anders lernen. Das wird hier gar nicht ausgenutzt.

Unknown hat gesagt…

@Ralf:
Genau solche "Entertainment"- bzw. "Zauber"-Videos kann ich mir auch nicht lange angucken, wenn ich etwas dabei lernen will.

Diese Videos sind einfach zu perfekt in ihrer Ausführung. Gerade bei TDD wünscht man sich da mehr Spontanität.

In der Hinsicht gelungener finde ich da diese Videoreihe:
http://www.jamesshore.com/Blog/Lets-Play

Da merkt man, dass James wirklich noch keine Idee hat, wo die Reise hingeht. Das wird besonders an seinen Kommentaren deutlich, während er coded. ;-D
(Und es zeigt sich auch, dass es nicht schaden kann, vorher mal über das Problem nachzudenken.)

Was auch noch sehenswert ist, ist diese Reihe:
http://lets-code.orfjackal.net/search/label/text-adventure

@GeH (und eigentlich alle ;-)):
Nun ja, TDD hin oder her. Dazu kann man stehen, wie man will.

Was mir beim TDD widerstrebt, ist, dass man zuerst den Test schreiben muss. Aber den Test wovon? Mit welchen Eingabewerten? Was sollen es für Ausgabewerte sein? Also ich brauche schon eine konkrete Vorstellung von dem, was ich umsetzen will/muss.

Ich fange immer lieber mit dem UI bzw. dem GUI an, nachdem ich erstmal einige Zeit über das Problem und die gewünschte Lösung sinniert habe. Das ist für mich immer noch griffiger und führt MICH zumindest am Schnellsten zum Ziel.