Wenn es bei TDD um Design geht, warum brauche ich es? [geschlossen]

10

TDD-Gurus sagen uns immer mehr, dass es bei TDD nicht um Tests geht, sondern um Design . Ich kenne also einige Entwickler, die wirklich tolles Design ohne TDD erstellen. Sollten sie dann TDD üben?

SiberianGuy
quelle
14
Wenn es ihnen ohne gut geht, brauchen sie es nicht. Nicht jede "Best Practice" funktioniert für alle.
Turm
1
Meine Antwort auf eine ähnliche Frage: programmers.stackexchange.com/questions/98485/…
Rei Miyasaka

Antworten:

18

TDD hilft mir nicht nur, das beste endgültige Design zu finden, es hilft mir auch, in weniger Versuchen dorthin zu gelangen.

Früher hatte ich zwei oder drei Stiche bei einem Problem, bevor ich mich für das beste Design entschied. Genau diese Zeit verbringe ich damit, Tests zu schreiben und mich auf das richtige Design zu konzentrieren. Und als Bonus habe ich eine Reihe wiederholbarer Tests. Sieg!

Trotzdem wird es unweigerlich Menschen geben, für die TDD nichts bietet. Solange sie am Ende noch automatisierte, wiederholbare Tests haben, ist das in Ordnung.

pdr
quelle
4
in weniger Versuchen wirklich?
SiberianGuy
3
Ja wirklich. TDD zwingt mich, über eine Klasse in Bezug auf den aufrufenden Code sowie dessen Funktionalität nachzudenken, da Sie zunächst den Code schreiben, von dem Sie erwarten, dass er schreiben kann, um die Klasse zu verbrauchen. Wenn ich eine Klasse "blind" schreibe, konzentriere ich mich eher auf das, was sie tut, als die aufrufende Klasse erwartet, was fast immer ein Fehler ist.
pdr
4
Sehen Sie, da ist wieder dieses Wort forced. Ich weiß nicht, warum Menschen nicht häufiger durch die Häufigkeit des Wortes "gezwungen" gestört werden, wie es in Diskussionen über TDD vorkommt. Man sollte nicht gezwungen sein müssen , etwas richtig zu entwerfen; Sie sollten lernen, wie man Dinge richtig gestaltet, und dies dann auch weiterhin tun, ohne dazu gezwungen zu werden, insbesondere wenn dieser Akt des Erzwingens so unglaublich zeitaufwändig ist.
Rei Miyasaka
3
@Rei: Menschen werden nicht öfter gestört, weil sie wissen, dass die andere Person wirklich "gedrängt" oder "geführt" bedeutet oder ... und hier ist eine Offenbarung, wenn Sie über testgetriebene Entwicklung sprechen ... vielleicht "getrieben". . Und ja, manche mögen feststellen, dass sie so natürlich denken, ohne getrieben zu werden, das habe ich in der Post gesagt. Aber Sie müssen Ihre Software noch testen, damit es Ihnen nicht viel besser geht.
pdr
3
Wenn jemand sagt "erzwingt modulares Design", wird er tatsächlich gezwungen. Es ist sehr schwierig (wenn nicht unmöglich), mit TDD ein nicht zusammensetzbares Design zu erstellen, und das ist gut so. Das Problem ist nicht das Endergebnis der Kraft; Es ist die Menge an niederträchtiger Anstrengung. Richtiges Design ist eine lehrbare und lernbare Fähigkeit, und es sollte Zeit für das Lernen aufgewendet werden. Außerdem sehen für TDD geschriebene Tests nicht so aus wie die Tests, die zum Auffinden von Fehlern geschrieben wurden. Wenn sie das tun, stimmt etwas nicht .
Rei Miyasaka
12

Was dieser spezielle TDD-Guru wirklich zu sagen versucht, ist nicht, dass TDD ein Designprozess ist (obwohl einige Leute es leider so interpretiert haben). Die Botschaft hier ist, dass die Verwendung eines Prozesses wie TDD, wenn Sie es richtig machen , dazu neigt, Ihr Gesamtdesign zu verbessern.

Das grundlegende Konzept ist viel älter als TDD. Design für Testbarkeit . Wenn Sie sich strikt an die SOLID- Prinzipien halten, insbesondere an das Prinzip der Einzelverantwortung , ist Code sehr einfach zu testen. Auf der anderen Seite, wenn Sie dazu neigen, in Ihrem Design etwas schlampiger zu sein, werden Sie wahrscheinlich den Prozess des Schreibens von Komponententests finden, um Sie dazu zu zwingen, dies häufiger zu tun, um die Frustration zu vermeiden, (a) herauszufinden, was erforderlich ist getestet werden und (b) mehr Zeit damit verbringen, Abhängigkeiten einzurichten, als die eigentlichen Tests zu schreiben.

Sie müssen nicht haben TDD folgen die Vorteile davon zu bekommen, aber es tut Hilfe , um die Tests zu schreiben früh - vorzugsweise sehr bald , nachdem Sie eine Klasse implementieren, wenn sie nicht vor oder während. Wenn Sie zu lange warten, laufen Sie Gefahr, dass die vom Autor erwähnten "Dirty Hybrid" -Tests nicht viel Wert haben, da sie spröde sind und beim harmlosen Refactoring leicht brechen - ganz zu schweigen von der Vergrößerung -skaliert einen äußerst schwierigen Prozess neu.

Sie können nicht wissen, ob Sie wirklich auf Testbarkeit ausgelegt sind, wenn Sie keine Tests schreiben, und zufällige "Funktionstests" mit nur 15% Codeabdeckung zählen nicht.

Natürlich können Sie gute Designs erstellen, ohne jemals einen einzigen Test zu schreiben - aber sind Sie sicher, dass es sich um großartige Designs handelt? Woher weißt du, ob sie durch Tests nicht eindeutig spezifiziert sind? Beim Testen werden viele Probleme aufgedeckt, und während ein QS-Prozess möglicherweise sichtbare Fehler findet, werden schlechte Entwurfsentscheidungen nicht aufgedeckt.

Aaronaught
quelle
1
Der Sinn eines guten Designs wird nicht nur getestet. Aber ja, TDD ist ein gutes Werkzeug, um fehlerhafte Designs zu erkennen.
Deadalnix
4

Einfache Antwort von jemandem, der TDD lernen möchte: Sie brauchen es nicht, aber der Hauptvorteil , den es Ihnen bietet, ist ganz einfach das Vertrauen : Vertrauen, dass Ihre Anwendung funktioniert. Vertrauen, dass die Anwendungsfälle erfüllt sind. Vertrauen Sie darauf, dass Ihre Logik für das "Foobar" -Modul einwandfrei ist. Vertrauen Sie darauf, dass Ihr Code richtig strukturiert ist, damit er sechs Monate später gewartet und erweitert werden kann, wenn der CEO eine neue verrückte Funktion hinzufügen möchte, über die er gelesen hat. Vertrauen Sie darauf, dass mit dem Wachstum Ihrer Anwendung der Grundstein dafür gelegt wurde, dass die Architektur nicht auseinanderfällt oder unordentliche Hacks erforderlich sind, um neue Funktionen zu bewerten.

Mir ist klar, dass das oben Genannte ein bisschen evangelisch klang, aber so sehe ich den Nutzen von TDD. Selbst wenn Sie mit TDD gute, solide und gut strukturierte Designs erstellen können, zwingt dies Ihre Hand dazu, die Dinge richtig zu machen, und beweist dann, dass die Dinge richtig gemacht werden, und bietet vor allem eine Grundlage, um die Dinge richtig zu halten. Von dem Moment an, in dem ich mich mit TDD beschäftigt habe, zwang mich die Verwendung dazu, den Code sauber zu machen und die richtigen Software-Engineering-Konzepte zu befolgen, wo ich sonst das "schnellstmögliche" tun würde, was oft zu chaotischem "Hack" -Code führte.

Wayne Molina
quelle
+1 TDD ist Feedback. Wie die meisten Feedback-Maßnahmen gehen, ist es ziemlich objektiv und vollständig automatisiert, sodass es von Teammitgliedern aller Schwierigkeitsgrade geteilt werden kann. Vor TDD war guter Code etwas, das Sie "fühlten" oder das irgendwann bestätigt wurde, nachdem die Benutzer die Software erhalten hatten. Je kürzer die Schleife, desto sicherer fühlen Sie sich. Leider neigt TDD zu Überbewusstsein, ein gutes Design zu "fühlen", aber es ist viel einfacher, sich selbst zu korrigieren.
Steve Jackson
2

Ich kann nur aus meiner Erfahrung sprechen. Für mich brachte TDD einige Dinge mit, die ich vorher nicht in meiner Toolbox für Entwicklungsgewohnheiten hatte. Es ist jedoch noch einmal erwähnenswert, dass TDD nicht für alles eine Lösung ist. Ich versuche immer, die explorations- und produktionsbereite Implementierung zu trennen. TDD in der Explorationsphase wird absolut nicht benötigt und verlangsamt sich sogar. Auf der anderen Seite bringt es für produktionsfertigen Code mehrere Vorteile, die auf kurze und lange Sicht für die psychische Gesundheit der Entwickler und das Karma des Projekts sehr wertvoll sind.

  • TDD bringt mich zum Nachdenken, bevor ich implementiere. Dies ist normalerweise eine sehr gute Vorgehensweise, die viele Shoot- und Forget-Lösungen verhindert
  • Es bringt mich dazu, in kleinen Teilen des Problems zu denken, und zwingt mich, die Lösung in kleine Teile zu zerlegen, die zusammenpassen.
  • Ich schreibe sehr entkoppelten Code, weil ich immer dann, wenn ich etwas stub / verspotten / fälschen muss, das nicht in das Problem passt, natürlich eine "WTF, warum sollte ich das tun, wenn ich nicht damit gekoppelt werden muss". . Und es lässt mich Verbindungen zwischen Dingen besser erkennen.
  • Es gibt mir eine Reihe von leicht ausführbaren Überprüfungen für meinen Code, so dass ich nicht durch schmerzhafte "var_dump", "p", "pp", "echo" -Stile des Debuggens von Code gehen muss. Es wird nur berichtet, was falsch ist, wann es falsch ist. Und wenn ich noch keinen Scheck dafür habe, muss ich nur einen einfachen Test hinzufügen, um ihn immer wieder zu überprüfen.
  • Es stellt sicher, dass mein Code funktioniert, wenn alle Tests vor der Bereitstellung bestanden wurden. Anstatt meine Nägel zu essen, esse ich einen Kuchen, trinke Kaffee und genieße meine Nachmittage.
  • High-Level-Tests sind sehr schön, wenn Sie etwas umgestalten müssen. Wenn mein Modul der Außenwelt einige Funktionen bieten muss und ich Funktions- / Integrations- / Gurkentests entwickelt habe, um zu beweisen, dass es richtig funktioniert, werde ich sehr mutig sein, diesen Code zum Teufel umzugestalten. Mehrmals wurde ich mit dem Code konfrontiert, der keine Tests hatte und überarbeitet werden musste. In diesem Fall gab es zwei Möglichkeiten, um in die Praxis umzusetzen. 1) Löschen Sie den Code. 2) Überspringen Sie die Änderungen und lassen Sie ihn unverändert.

Es gibt eine Sache, die TDD nicht behebt. Wenn Sie nicht wissen, wie Sie das Objekt erstellen sollen, das Sie erstellen, erstellt TDD keine Lösung für Sie. Sie benötigen ein grobes "Design" oder einen Überblick über das Problem und die Lösung. Mit TDD können Sie es einfach eleganter und wartbarer mit dem Code höherer Qualität implementieren.

Schließlich denke ich lieber in BDD-Begriffen, die sich auf TDD-Praktiken stützen. Mit BDD kann ich eine Lösung mithilfe des Vokabulars der Domäne implementieren und die Software besser an das Problem anpassen.

ivanjovanovic
quelle
1

Es kann viele Wege geben, um großartiges Design zu erreichen, und es gibt zweifellos viele verschiedene Interpretationen dessen, was "großartig" - oder sogar "gut" ausmacht. Ich vermute, die meisten TDDer würden Ihnen in Bezug auf die Definition nicht zustimmen. Wenn wir uns den Code ansehen, den Sie für großartig halten, würden wir ihn für weniger als großartig halten. TDD führt uns zu einigen sehr spezifischen Eigenschaften, und diese Eigenschaften sind in Nicht-TDD-Code selten zu finden.

Testbarkeit ist offensichtlich eine dieser und die übergeordnete Eigenschaft. Extrem kleine Methoden und Klassen sind möglicherweise ein Untermerkmal, und dies führt zu einer hervorragenden Benennung. Vielleicht kennen Sie Programmierer, die diese Eigenschaften erreichen, ohne TDD zu machen, aber ich nicht.

Carl Manaster
quelle
1
Sie werden mit ziemlicher Sicherheit dieselben Eigenschaften in Code finden, der durch einen Wasserfallprozess erzeugt wird, z. B. für das Militär, den Weltraum usw. Ich nehme an, es ist wahr, dass sie in den halbherzigen Versionen von Agile und / oder Wasserfall, in denen praktiziert wird, nicht üblich sind die meisten Organisationen für alltägliche Projekte.
Aaronaught
@Aaronaught Erzähl das dem Mars Climate Orbiter Team. :-)
Eric King
Ich hatte einige Erfahrungen mit dem Wasserfallprozess bei militärischen Projekten ohne Waffen in den 90er Jahren und auch viele Diskussionen über Wasserkühler mit Veteranen anderer militärischer Anwendungen. Der allgemeine Konsens war, dass die Wasserfallmethode und die Kosten-Plus-Abrechnung fehlerhafte Systeme hervorbrachten, die sehr schwer zu warten waren.
Kevin Cline