TDD negative Erfahrung

94

Was ist eine negative Seite Ihrer TDD-Erfahrung? Finden Sie Babyschritte (die einfachste Lösung, um Testgrün zu machen) ärgerlich und nutzlos? Finden Sie wertlose Tests (wenn der Test anfänglich Sinn hat, aber in der endgültigen Implementierung die gleiche Logik wie bei anderen Tests prüft) wichtig für die Wartung? usw.

Die obigen Fragen beziehen sich auf Dinge, die mir während meiner TDD-Erfahrung unangenehm sind. Ich bin also interessiert, ob andere Entwickler ähnliche Gefühle haben und was sie über sie denken.

Wäre dankbar für die Links zu Artikeln, die negative Seiten von TDD beschreiben (Google wird von positiven und oft fanatischen Artikeln gefüllt).

Idsa
quelle
10
Ich vermute, dass Sie nicht viele ehrliche Antworten über die negativen Erfahrungen der Menschen hören werden, da TDD sich immer noch in einem Zustand des "Early Adopters" befindet und die meisten Menschen, die interessiert und engagiert genug sind, es zu versuchen, nicht objektiv genug sind bewerte es nach seinen relativen Vorzügen. Es dauert in der Regel mehrere Jahre, bis die Branche die langfristigen Auswirkungen neuer Verfahren und Techniken wirklich erkannt hat, und selbst dann ist es aufgrund fehlender Kontrollen schwierig, klare Antworten zu erhalten. Trotzdem gute Frage und viel Glück beim Erhalten hilfreicher Antworten!
Aaronaught
20
Haben Sie Probleme, Negativität im Internet zu finden ?!
Eric Wilson
4
@Job (und möglicherweise andere): Vergiss nicht, dass er nach TDD gefragt hat, nicht nach Unit-Tests. TDD! = Komponententest.
n1ckp
2
Ich bin versucht, diese Frage zu beantworten, aber ich möchte nicht wirklich loslegen, weil es meinen halben Tag in Anspruch nehmen wird.
Rei Miyasaka
2
Wenn ich genug Zeit mit Bugs verbringe, um weniger Zeit mit dem Schreiben von Tests für jede einzelne Sache zu verbringen, die ich schreibe, bevor ich sie schreibe, werde ich kein Test-first-all-things-TDD anwenden. Ich werde stattdessen beschämt meinen Kopf hängen lassen und mich auf die Suche nach einer neuen Karriere machen. Nicht über Fehler, die Sie sagen? Design? Ja. Das ist es. Genau das ist es. Und Sie haben verdammt noch mal nichts über robustes Design gelernt, indem Sie sich ein Sicherheitsnetz und eine Lizenz gegeben haben, um weiter dumm zu arbeiten. Legen Sie die IDE beiseite und versuchen Sie, Ihren Code zu lesen, wenn Sie das eigentliche Problem erkennen möchten.
Erik Reppen

Antworten:

94

Wie alles, was unter das Banner "Agile" fällt, klingt TDD theoretisch gut, aber in der Praxis ist es nicht so klar, wie gut es ist (und wie bei den meisten "agilen" Dingen wird Ihnen auch gesagt, dass Sie es nicht tun, wenn Sie es nicht tun mag es, du machst es falsch).

Die Definition von TDD ist nicht in Stein gemeißelt: Leute wie Kent Beck fordern, dass ein nicht kompilierter Test vor einer einzelnen Codezeile geschrieben werden muss und dass jede einzelne Codezeile geschrieben werden muss, um einen fehlgeschlagenen Test zu bestehen. Das Design im Vordergrund ist minimal und alles ist angetriebendurch die Tests. Es funktioniert einfach nicht. Ich habe eine große Unternehmens-App gesehen, die mit dieser Methode entwickelt wurde, und ich hoffe, dass dies der schlechteste Code ist, den ich in meiner Karriere gesehen habe (es wird nicht mehr weit sein; und das, obwohl einige talentierte Entwickler daran gearbeitet haben). Aus dem, was ich gesehen habe, ergibt sich eine große Anzahl von schlecht durchdachten Tests, die hauptsächlich das Auftreten von Funktionsaufrufen bestätigen, dass Ausnahmen ausgelöst werden, wenn Variablen null sind und das spöttische Framework eine gründliche Übung erhält (whoop-de-whoop); Ihr Produktionscode ist stark an diese Tests gebunden, und der Traum vom ständigen und einfachen Refactoring wird nicht wahr. Tatsächlich ist es sogar noch unwahrscheinlicher, dass Leute fehlerhaften Code reparieren, da der gesamte Test fehlerhaft ist.

Umgekehrt habe ich die Argumentation gehört, dass TDD bedeutet, die Tests im Vorfeld als Teil der Planungsphase auf hohem Niveau zu entwerfen - neben dem architektonischen Entwurf. Diese Tests können sich während der Entwicklung ändern, sobald weitere Informationen verfügbar sind. Sie wurden jedoch sorgfältig geprüft und bieten eine gute Anleitung, was der Code tatsächlich tun sollte. Für mich macht das vollkommen Sinn.

user23157
quelle
7
+1 "Die Tests im Vorfeld als Teil der Planungsphase auf hohem Niveau zu gestalten - neben dem architektonischen Entwurf" Klingt für mich auch viel vernünftiger.
Steven Jeuris
11
@Aaronaught Agile bedeutet nicht, keine Planung, sondern nur, rechtzeitig zu planen.
Adam Jaskiewicz
25
@Adam Jaskiewicz: Ich liebe die Sache "keine Vorausplanung". Komm schon, Planung ist per Definition im Voraus . Wenn Sie nicht im Voraus planen, aber während der Veranstaltung, planen Sie überhaupt nicht. du improvisierst ;-)
CesarGon
34
@Adam - "Springen die Leute am ersten Tag einer Iteration wirklich direkt in die Programmierung?" ähm yep. Das ist "agiler" Mann. Zuletzt habe ich gearbeitet (und wurde entlassen, weil ich nicht "agil" war), sie haben einen gesamten dreimonatigen Veröffentlichungszyklus durchgeführt, ohne jemals eine einzige Codezeile geplant oder eine einzige Dokumentationsseite erstellt zu haben. Und ja, der Code war schrecklich und die Software war langsam, klobig und fehlerhaft. Am Tag meines Beitritts teilte mir der Manager mit Stolz mit, dass sie "das agilste Geschäft in London" seien. Sie waren sicher.
7
Kann ein weiteres Problem hinzufügen: Solange es den Test besteht, muss es gut sein. Es spielt keine Rolle, dass der Test selbst möglicherweise fehlerhaft ist und daher falsch negative und / oder falsch positive Ergebnisse liefert. Und natürlich erfordert "100% Testabdeckung" und alles, was solche hat, ist per Definition perfekt, was zu nutzlosen Tests führt, die eigentlich nichts testen, sondern nur geschrieben werden, um diese 100% Abdeckung zu erreichen, Code, der nicht dokumentiert ist, weil Ihr Abdeckungszähler Kommentare zählt als aufgedeckter Code usw. usw.
jwenting
66

Dieses ( Clojure- Autor) Rich Hickey-Interview enthält Folgendes. Ich fühle mich 100% sympathisch:

Das Leben ist kurz und es gibt nur eine begrenzte Anzahl von Stunden an einem Tag. Wir müssen also entscheiden, wie wir unsere Zeit verbringen. Wenn wir damit verbringen, Tests zu schreiben, dann verbringen wir keine Zeit damit, etwas anderes zu tun. Jeder von uns muss beurteilen, wie er seine Zeit am besten verbringen kann, um seine Ergebnisse sowohl in quantitativer als auch in qualitativer Hinsicht zu maximieren. Wenn die Leute denken, dass fünfzig Prozent ihrer Zeit damit verbracht werden, Tests zu schreiben, maximieren sie ihre Ergebnisse - okay für sie. Ich bin sicher, dass das für mich nicht zutrifft - ich würde diese Zeit lieber damit verbringen, über mein Problem nachzudenken. Ich bin mir sicher, dass dies für mich zu besseren Lösungen mit weniger Fehlern führt als jede andere Nutzung meiner Zeit. Ein schlechtes Design mit einer vollständigen Testsuite ist immer noch ein schlechtes Design.

Eine weitere ähnliche Aussage von Donald Knuth in Coders at Work-Buchinterview , kopiert von hier :

Seibel: Apropos praktische Arbeit, während Sie an der Kunst der Computerprogrammierung arbeiteten, haben Sie eine zehnjährige Pause eingelegt, um Ihr Schriftsystem TeX zu schreiben. Soweit ich weiß, haben Sie die erste Version von TeX nicht auf dem Computer geschrieben.

Knuth: Als ich 1977 und 1978 ursprünglich TeX geschrieben habe, hatte ich natürlich keine geschulte Programmierung, aber ich hatte strukturierte Programmierung. Ich schrieb es in einem großen Notizbuch in Langschrift mit Bleistift. Sechs Monate später, nachdem ich das ganze Projekt durchgearbeitet hatte, begann ich, in den Computer zu tippen. Und habe das Debuggen im März 1978 gemacht, während ich im Oktober 1977 mit dem Schreiben des Programms begonnen hatte. Der Code dafür befindet sich in den Stanford-Archiven - alles in Bleistift - und natürlich würde ich zurückkehren und eine Subroutine ändern, während ich lernte, wie sie sein sollte. Dies war ein System der ersten Generation, daher waren viele verschiedene Architekturen möglich und mussten verworfen werden, bis ich eine Weile damit gelebt hatte und wusste, was da war. Und es war ein Henne-Ei-Problem: Sie konnten erst dann Schriften setzen, wenn Sie Schriften hatten, und dann konnten Sie erst dann Schriften setzen. Die strukturierte Programmierung brachte mich jedoch auf die Idee, Invarianten zu erstellen und zu wissen, wie man Black Boxes herstellt, die ich verstehen konnte. Ich hatte also die Gewissheit, dass der Code funktionieren würde, wenn ich ihn endlich debuggen würde. Ich hatte das Gefühl, dass ich viel Zeit sparen würde, wenn ich sechs Monate warten würde, bevor ich etwas teste. Ich hatte genug Vertrauen, dass der Code ungefähr richtig war.

Seibel: Und die Zeitersparnis wäre, dass Sie keine Zeit damit verbringen würden, Gerüste und Stubs zu bauen, um unvollständigen Code zu testen?

Knuth: Richtig.

Joonas Pulakka
quelle
24
Ich denke, Sie müssen sich die Art der Arbeit ansehen, die Sie tun. Knuth und Hickey sprechen über das Design neuer (innovativer) Anwendungen. Wenn Sie sich ansehen, wo TDD beliebt ist (breite Übergeneralisierung), dann werden Sie feststellen, dass die meisten TDD-geschriebenen Anwendungen bereits eine bekannte Architektur haben.
Sebastiangeiger
4
Ich kann sehen, was Rich Hickey bedeutet, aber ich möchte Folgendes hinzufügen: Nach meiner Erfahrung müssen Sie beim Schreiben der Tests wirklich über Ihr Design nachdenken und darüber, wie Sie Ihren Code testbar machen Erfahrung, führt zu besserem Design.
Niklas H
3
Da das OP nach negativen Erfahrungen mit TDD fragt, scheint keines Ihrer Beispiele für diese Frage relevant zu sein, da keines ein Beispiel für TDD in Aktion zeigt.
Winston Ewert
5
@Michael Borgwardt: Es ist relativ einfach, Tests zu einem vorhandenen, guten Design hinzuzufügen, um Fehler in der Implementierung zu beseitigen. Schlechtes Design loszuwerden, bedeutet jedoch häufig eine vollständige Neufassung. Daher sollte das Hauptziel darin bestehen, das richtige Design zu finden . Die Ausführung ist später einfacher zu beheben.
Joonas Pulakka
4
Die meisten Geschäftsanwendungen haben nicht den Vorteil, von Donald Knuth geschrieben und / oder gewartet zu werden. Die Lebensdauer einer Anwendung ist in der Regel VIEL länger als bei der Erstentwicklung. Ich wünschte, die Leute hätten mehr Tests zu meinem aktuellen Projekt geschrieben. Jetzt ist Wartung wie ein Minenfeld unendlicher Regressionen.
Matt H
58

Meine negativen Erfahrungen mit TDD waren meine ersten. TDD klang großartig für mich, ich hatte jahrelang QS gemacht und immer noch die Schrecken im Kopf gehabt. Ich wollte jeden Fehler ersticken, bevor er zu einem Build wurde. Leider garantiert die Verwendung von TDD nicht, dass Sie gute Tests schreiben. Tatsächlich bestand meine anfängliche Veranlagung darin, einfache Tests zu schreiben, die einfachen Code generierten. Wirklich einfacher Code, der nur wenige Abstraktionen enthielt. Wirklich einfache Tests, die mit den Interna der Klasse verflochten waren. Und sobald Sie ein paar tausend kleine Tests durchgeführt haben, haben Sie sicher nicht das Gefühl, dass Sie sich schneller bewegen, wenn Sie hundert davon ändern müssen, um Ihren Code für die Verwendung des sehr wichtigen Domain-Konzepts X zu überarbeiten.

Das Licht ging für mich an - TDD ist keine Testfähigkeit. Es ist eine Designfähigkeit. Es kann Sie nur zu gutem, einfachem und praktikablem Code führen, wenn Sie sich der Konstruktionsanweisungen, in die es Sie führt, stets bewusst sind. Wenn Sie Tests für die Codeabdeckung schreiben, werden Sie spröde Tests erstellen. Wenn Sie Tests schreiben, um Ihre Abstraktionen zu entwerfen, ist dies nur eine strengere Methode zum Schreiben von Top-Down-Code. Sie können den Code zuerst aus der Sicht des Anrufers sehen, was Sie ermutigt, sein Leben zu vereinfachen, anstatt die Interna einer Klasse nach außen zu spiegeln.

Ich denke, TDD ist nützlich, aber ich bin nicht dogmatisch. Wenn diese "No-Value-Tests" die Wartung erschweren - löschen Sie sie! Ich behandle Tests genauso wie den Rest des Codes. Wenn es weg überarbeitet werden kann und die Dinge einfacher macht, dann mach es!

Ich habe es nicht persönlich gesehen, aber ich habe gehört, dass einige Orte die Codeabdeckung und die Anzahl der Tests nachverfolgen. Wenn das Sammeln von Metriken ein Nebeneffekt von TDD ist, könnte ich das auch negativ sehen. Ich werde begeistert 1000 Codezeilen löschen, und wenn das 20 Tests überflüssig macht und meine Code-Abdeckung in% senkt, na ja.

Steve Jackson
quelle
7
Sie haben es in Absatz 2 geschafft.
Sheldon Warkentin
4
"Ich habe es nicht persönlich gesehen, aber ich habe gehört, dass manche Orte die Codeabdeckung und die Anzahl der Tests nachverfolgen." Ich habe in einer solchen Umgebung gelebt und in der Tat wurde kein Code jemals herausgeworfen, da dies dazu führen würde, dass ein Test fehlschlug. Bis ich anfing, die eigentlichen Tests zu debuggen und herausfand, dass viele von ihnen so schwerwiegende Fehler aufwiesen, dass sie den Code zwangen, falsche Ergebnisse zu liefern, damit die Tests bestanden wurden. Zu diesem Zeitpunkt habe ich die Frage geprägt: "Wer testet die Tests?" Auf diese Frage hatte ich bisher noch nie eine zufriedenstellende Antwort von der TDD-Community. Unit-Tests für Unit-Tests, jemand?
10.
@jwenting - Und diese Anekdote unterstützt die Argumentation von Rei ziemlich gut. Ich habe festgestellt, dass der Regressionsschutzaspekt von TDD in der Praxis übertrieben ist, auch wenn es sich theoretisch um eine solide Idee handelt. Die Tests müssen auf der gleichen Ebene wie der Produktionscode gehalten werden, damit sie funktionieren, und es ist etwas unnatürlich, Nicht-Produktionscode auf diese Weise zu behandeln. usw. die ganze Zeit.
Steve Jackson
"Wirklich einfache Tests, die mit den Interna der Klasse verflochten waren" <- genau dort liegt Ihr Problem. Test nur an öffentlichen Schnittstellen. TDD! = UT
Steven A. Lowe
2
@ StevenA.Lowe - Ich weiß das jetzt, aber vor 9 Jahren war es nicht so klar :) "TDD ist keine Testfähigkeit"
Steve Jackson
41

Ich werde hier auf die Nerven gehen und mit brutaler Ehrlichkeit erklären, dass es buchstäblich eine rituelle Zeitverschwendung ist. (In den meisten Situationen.)

Ich habe ein Buch über Unit Testing gekauft, in dem auch TDD behandelt wurde, und obwohl ich den Vorteilen von UT zustimme, habe ich es nach ungefähr hundert Stunden TDD-Test aus einer Vielzahl von Gründen aufgegeben. Ich schreibe hier eine Art Cross-Posting , aber TDD:

  1. Ist keine bessere Dokumentation als echte Dokumentation.
  2. Fängt keine Bugs oder Regressionen .
  3. Das macht meine Entwürfe nicht wirklich besser, als es letztendlich der Fall ist, wenn ich einige Konzepte zur funktionalen Programmierung und Kompositionsfähigkeit verwende .
  4. Ist die Zeit, die besser für Codeüberprüfungen oder das Polieren von Dokumentationen und Spezifikationen verwendet werden könnte.
  5. Verleiht Managern ein falsches Sicherheitsgefühl, wenn sie eine Liste mit Hunderten von grünen Symbolen sehen.
  6. Verbessert die Produktivität bei der Implementierung von Algorithmen mit begrenzten Eingabe-Ausgabe-Zuordnungen.
  7. Ist ungeschickt, dass Sie vielleicht wissen, was Sie als Ergebnis von TDD tun, aber Sie verdienen kein Verständnis dafür, warum es so gut funktioniert, warum Ihre Designs so herausstechen, wie sie es tun.

Ein weiteres Problem ist der umstrittene Grad an Perfektion, bis zu dem TDD erfolgreich durchgeführt werden muss. Einige bestehen darauf, dass Sie nur leiden werden, wenn TDD nicht von Beginn des Projekts an von allen Teammitgliedern beharrlich durchgeführt wird. Andere bestehen darauf, dass niemand TDD nach dem Buch tut. Wenn beides zutrifft, dann leiden die TDD-Praktizierenden, ob sie es bemerken oder nicht.

Wenn man argumentiert, dass man durch TDD-artiges Arbeiten zu Entwürfen kommt, die mit TDD problemlos funktionieren, gibt es natürlich viel schnellere Möglichkeiten, dies zu erreichen - nämlich durch das tatsächliche Studieren der Konzepte von Kompositionsfähigkeit. Es gibt viele Ressourcen, sogar eine Menge strenger mathematischer Theorie (hauptsächlich in der funktionalen Programmierung, aber auch in anderen Bereichen). Warum verbringen Sie nicht Ihre ganze TDD-Zeit mit Lernen ?

In kultureller Hinsicht zeigt TDD Symptome einer rituellen Praxis. Es reitet auf Schuld; es fördert das Verfahren über das Verstehen; Es hat Unmengen von Doktrinen und Slogans. Die Wikipedia-Definition des Wortes "Ritual" ist in der Tat ziemlich zutreffend:

In der Psychologie wird der Begriff Ritual manchmal im technischen Sinne für ein sich wiederholendes Verhalten verwendet, das systematisch von einer Person verwendet wird, um Angstzustände zu neutralisieren oder ihnen vorzubeugen. Es ist ein Symptom für eine Zwangsstörung.

Rei Miyasaka
quelle
Sehr interessante Perspektive bezüglich: Ritual. In manchen Kreisen hat man auch das Gefühl, dass das Engagement eines Programmierers für sein Handwerk nur proportional zu seiner Einhaltung der TDD ist.
Yalestar
Ich würde sagen, in einigen Situationen kann es ein Design verbessern, aber meistens muss das Design in hohem Maße modular mit einer sehr gut definierten und einfach zu verwendenden öffentlichen Oberfläche sein. In solchen Fällen kann das Schreiben der Tests vor der eigentlichen Implementierung der Bibliothek helfen, die Fehler in der öffentlichen Schnittstelle zu beseitigen und diese Modularität zu erzwingen.
10.
8
@jwenting Menschen machen TDD, weil sie nicht wissen, was ein modulares Design ausmacht, und deshalb niemals ihre 35-Zoll-Stützräder von ihren 40-Zoll-Fahrrädern nehmen können. Ein modulares Design zu erstellen ist immer eine überschaubare Aufgabe, wenn Sie die Konzepte verstehen, da jedes Dilemma in Ihrem Design eine überschaubare Größe hat, da es sich in seiner Konzeption im modularen Prozess befindet. Ich bin mir nicht einig, dass TDD die Modularität effektiv erzwingt, aber ich bin mir nicht einig, dass man gezwungen werden muss, modulare Designs zu erstellen. Modulares Design ist eine perfekt unterrichtbare und lernbare Fähigkeit.
Rei Miyasaka
@jwenting In Bezug auf die Benutzerfreundlichkeit öffentlicher Schnittstellen gibt es unter TDD-Praktikern zwei Denkansätze, die beide unerwünscht sind: Machen Sie alles öffentlich, damit es getestet werden kann, oder lassen Sie Dinge privat, wenn sie ohnehin nicht getestet werden sollten . Ersteres erzwingt, dass Endbenutzern unnötige Implementierungsdetails angezeigt werden (die möglicherweise missbraucht oder ausgenutzt werden können), und letzteres erzwingt, dass Komponententests den Systemtests näher kommen. Sicher, Sie könnten Unit-Test-Tools verwenden, um auf Privates zuzugreifen, aber das ist in TDD nicht sehr sinnvoll.
Rei Miyasaka
1
@Kall In diesem Interview sagt er "ungefähr 15 bis 35% mehr Zeit" - nicht nur 15%, wie Sie ihn zitiert haben. Die Studie bezieht sich auch nur auf Java / C ++ / C # (wahrscheinlich C # 2, wenn das Datum angegeben ist) - alle Sprachen des gleichen zwingenden OOP-Paradigmas. Ich bin mit Sicherheit mehr als 15% und wahrscheinlich mehr als 35% produktiver in einer funktionalen Sprache (und sogar in C # 3), und ich produziere viel weniger Fehler beim Schreiben von zustandslosem, zusammensetzbarem Code - die gleichen Fehler, die beim Testen behoben werden. weil beide Dinge genau die gleichen Arten von Problemen lösen. Mit anderen Worten, sicher, 60-90% weniger Bugs, aber im Vergleich zu was ?
Rei Miyasaka
18

Ein weiteres Problem mit TDD, das mir aufgefallen ist, ist:

TDD führt zu einer unbeabsichtigten Verlagerung des Fokus des Entwicklungsteams vom Qualitätscode auf Testfälle und Code Coverage! Ich persönlich mochte TDD nicht, weil es mich weniger kreativ macht und die Softwareentwicklung zu einem langweiligen mechanischen Prozess macht ! Unit-Testcases sind nützlich, wenn sie mit Bedacht eingesetzt werden, werden jedoch zur Last, wenn das Ziel der Softwareentwicklung behandelt wird.

Ich kenne einen Manager, der technisch langweilig ist, als er von TDD besessen war. Es war so magisch für ihn, dass er glaubte, mit am wenigsten wartbarem Code magische Lösungen für alle Probleme in seiner schlecht strukturierten Software zu finden. Um nicht zu sagen, was mit diesem Projekt passiert ist - es ist in seinen Händen kläglich gescheitert, während alle seine Testfälle grün waren. Ich denke, TDD hat ihm geholfen, statistische Informationen wie "99/100 meiner Fälle sind grün" usw. zu erhalten, und das war der Grund für seine Besessenheit, da er niemals in der Lage sein würde, die Qualität zu bewerten oder Verbesserungen im Design vorzuschlagen.

Kiran Ravindranathan
quelle
2
Klingt nach PHB Hölle! Es erinnert mich an Unternehmen, die Bonusmodelle einführen - was natürlich passiert, ist, dass Entwickler anstatt sich auf Qualitätscode zu konzentrieren, sich darauf konzentrieren, die Bonusanforderungen zu erfüllen. Unvermeidlich erhalten Sie crappier Code. (Hier gibt es auch eine Analogie zur aktuellen Bankenkrise :-))
TrojanName
Nun, TDD ist keine Projektmanagement-Technik, daher ist es kein Wunder, dass Ihr Möchtegern-Manager versagt hat. Andererseits fühle ich mich nicht weniger kreativ, ich fühle mich sogar kreativer, weil die Entwicklung von Tests mir automatisch eine andere Sicht auf meinen Code gibt. Ich stimme jedoch zu, dass der Fokus auf Produktionscode liegen muss und Tests eine gute Software-Architektur nicht durcheinander bringen sollten.
Alex
Die Codeabdeckung ist ein Anliegen von Unit Testing, nicht von TDD. TDD kümmert sich nur um Funktionen und Tests über öffentliche Schnittstellen.
Steven A. Lowe
14

Meine primäre negative Erfahrung ist der Versuch, mit TDD den Code eines anderen Programmierers zu bearbeiten, der keine Tests oder sehr, sehr einfache Integrationstests hat. Wenn ich eine Funktion hinzufüge oder ein Problem mit dem Code behebe; Ich würde es vorziehen, zuerst einen Test zu schreiben (auf TDD-Weise). Leider ist der Code eng miteinander verbunden, und ich kann nichts ohne viel Umgestaltung testen.

Das Refactoring ist ohnehin eine großartige Übung, aber es ist erforderlich , den Code in einen testbaren Zustand zu versetzen. Und nach diesem Schritt habe ich keine Kontrolle mehr, um festzustellen, ob meine Änderungen irgendetwas kaputt gemacht haben. kurz die Anwendung auszuführen und jeden Anwendungsfall zu untersuchen.

Auf der anderen Seite wird das Hinzufügen von Funktionen / Beheben von Fehlern zu einem TDD-Projekt sehr einfach. Code, der mit TDD geschrieben wurde, ist normalerweise ziemlich entkoppelt von kleinen Teilen, mit denen gearbeitet werden kann.

TDD ist in jedem Fall eine Richtlinie. Folgen Sie ihm bis zu dem Punkt, an dem Sie maximale Wirksamkeit erzielen. Ordentliche Testabdeckung und entkoppelter Code, gut geschriebener Code.

Sheldon Warkentin
quelle
1
Wenn es schwierig ist, Unit-Tests zu schreiben, gibt es im Allgemeinen eine schlechte Trennung der Bedenken. Ich sehe das nicht als Fehler von TDD, wenn überhaupt, macht es diese Probleme schnell offensichtlich.
Tom Kerr
7
Das ist keine negative Erfahrung mit TDD, das ist eine negative Erfahrung mit schlechtem Code.
Rei Miyasaka
13

Ich habe die Erfahrung gemacht, dass ich mich manchmal zu sehr auf meine Tests verlasse, wenn es um das Design des Systems geht. Ich bin im Grunde zu klein in den Details der Implementierung, um den Schritt zurück zu wagen, um das Gesamtbild zu betrachten. Dies führt häufig zu einer unnötig komplexen Konstruktion. Ich weiß, ich sollte den Code überarbeiten, aber manchmal habe ich den Eindruck, dass ich viel Zeit sparen könnte, wenn ich öfter einen Schritt zurück mache.

Das heißt, wenn Sie einen Rahmen wie Schienen haben, bei dem Ihre architektonischen Entscheidungen sehr begrenzt sind, sind diese Probleme im Grunde nicht vorhanden.

Ein weiteres Problem ist, wenn Sie Ihren Tests blind vertrauen. Die Wahrheit ist, dass Ihre Tests - wie jeder andere Code - auch Fehler aufweisen können. Seien Sie für Ihre Tests genauso kritisch wie für Ihre Implementierung.

sebastiangeiger
quelle
2
Vielleicht solltest du ein paar Tests für deine Tests schreiben! : p ...... I Kid, I Kid
Aren
+1 +1 +1 +1 (wenn ich 3 Dummy-Konten hatte). Satz 2 ist sehr aufschlussreich und frei von der viel zu weit verbreiteten TDD-Bestätigungsverzerrung.
tgm1024
11

Als großer Fan von TDD sehe ich manchmal diese Nachteile

  • Versuchung, zu viele Tests zu schreiben, um eine fast 100% ige Codeabdeckung zu erreichen. Meiner Meinung nach ist es nicht notwendig, Tests zu schreiben
    • für einfache Eigenschafts-Getter / Setter
    • für jeden Fall, wenn eine Ausnahme ausgelöst wird
    • das prüft die gleiche Funktionalität durch verschiedene Schichten. (Beispiel: Wenn Sie keine Möglichkeit haben, die Eingabevalidierung für jeden Parameter zu überprüfen, ist es nicht erforderlich, alle diese Tests auch durch einen Integrationstest zu wiederholen.)
  • Wartungskosten für Testcode für ähnliche Tests, die nur geringfügig variieren (durch Code-Duplikation (auch bekannt als Copy-Paste-Inheritance)). Wenn Sie bereits eine haben, ist es einfach, eine ähnliche zu erstellen. Wenn Sie den Testcode jedoch nicht umgestalten, müssen Sie möglicherweise einige Zeit aufwenden, um die Tests zu korrigieren, wenn sich die Implementierungsdetails Ihres Geschäftscodes ändern.

  • Wenn Sie unter Zeitdruck stehen , könnten Sie versucht sein, defekte Tests zu eliminieren (oder sie zu kommentieren), anstatt sie zu reparieren . Auf diese Weise verlieren Sie die Investition in die Tests

k3b
quelle
2
+1: "Versuchung, zu viele Tests zu schreiben, um fast 100% Codecoverage zu erreichen.": Ich bin einmal in diese Falle geraten, und nachdem ich so viele Stunden mit dem Schreiben all dieser Komponententests verbracht habe, waren die einzigen drei Fehler, die ich in meinem Code gefunden habe nicht durch die Unit-Tests abgedeckt und konnte leicht durch das Debuggen des Codes Schritt für Schritt gefunden werden.
Giorgio
9

Ich habe als Spieleentwickler bisher noch kein einziges Szenario erlebt, in dem sich TDD gelohnt hat. Und in diesem Fall handelte es sich um einen Code, der rein mathematischer Natur war und einen soliden Ansatz zum gleichzeitigen Testen einer großen Anzahl von Randfällen erforderte - eine seltene Notwendigkeit.

Vielleicht wird irgendwann etwas meine Meinung ändern, aber bei XP-Praktiken ist die Idee der unbarmherzigen Umgestaltung und der Entwicklung des Codes in seiner eigenen Form weitaus wichtiger und führt zu der größten Produktivität für mich, vgl. ein Zitat aus einem Artikel von James Newkirk :

Einfachheit - "Was ist das Einfachste, was funktionieren könnte?"
Die Botschaft ist sehr klar. Entwerfen und schreiben Sie Ihre Software unter Berücksichtigung der heutigen Anforderungen. Versuchen Sie nicht, die Zukunft vorwegzunehmen, sondern lassen Sie die Zukunft sich entfalten. Dies geschieht häufig auf sehr unvorhersehbare Weise, wodurch die Kosten für die Antizipation oft zu hoch sind. "

Die Konzepte des Mutes und der Verschärfung der Rückkopplungsschleifen , die er erwähnt, sind meines Erachtens auch der Schlüssel zur Produktivität.

Techniker
quelle
9
Das Problem ist, woher wissen Sie ohne Unit-Tests, dass Ihr gnadenloses Refactoring zu Code führt, der dasselbe tut? Nach meiner Erfahrung kann das Schreiben von Tests und Code je nach Problem weniger Zeit in Anspruch nehmen als das Schreiben des Codes alleine! Der Grund ist hauptsächlich die Tatsache, dass ich bei einigen Problemen einen Re-Faktor ausprobieren und automatisch viel schneller erneut testen kann, als ich es manuell testen konnte, was die Geschwindigkeit der Iterationen erheblich erhöhen kann.
Mark Booth
6
Bei Spielen sind die Ergebnisse sehr oft zu sehen. Wenn sie gesehen werden können und gut genug erscheinen, werden sie akzeptiert, da ein Spiel sowieso eine subjektive Erfahrung sein soll. Zum anderen nehmen z. Diablo 2 als Beispiel, die Anzahl der Fehler in Kampfformeln zeigte, wo TDD einen enormen Wert gebracht und ihnen enorme Arbeit an Patches erspart hätte. Für sehr genau definierte Probleme wie das Lösen von Gleichungen und wenn diese zur Laufzeit nicht durch visuelle Ausgaben beurteilt werden können, ist TDD ein Muss, um die Korrektheit sicherzustellen. Aber das ist ein kleiner Bruchteil des Codes in den meisten Spielen.
Ingenieur
Erwähnenswert ist auch, dass es aufgrund der Geschwindigkeit, mit der Simulationen ausgeführt werden, besser ist, die Variablen während der Ausführung in Echtzeit auf dem Bildschirm zu betrachten, als mit Protokolldateien mit Millionen Zeilen zu arbeiten, um nachträglich nachzuschauen.
Ingenieur
3
Nach meiner Erfahrung erleichtern Unit-Tests das Refactoring erheblich .
Tom Kerr
1
@Nick Das große Problem in der Spielebranche sind die Fristen, die immer lauten: "Wir mussten vor einem halben Jahr liefern". Ich denke, die Zeit spielt gegen Unit-Tests in zeitlich begrenzten Umgebungen. In einigen Fällen ist es keine richtige Entscheidung, aber in den meisten Fällen ist der Versand ohne Testschreiben schneller. Kommt drauf an, kommt
drauf an
7

Meine negative Erfahrung mit TDD ist, dass ich einfach weiß, wo ich anfangen soll! Zum Beispiel werde ich versuchen, etwas TDD zu machen, und entweder habe ich keine Ahnung, wo ich anfangen soll, das Testen trivialer Dinge zu unterbinden (kann ich ein FooObjekt neu anlegen, kann ich a Quuxan das übergeben Bazund dergleichen. Tests, die nichts testen) ), oder wenn ich versuche, es in ein vorhandenes Projekt zu implementieren, stelle ich fest, dass ich verschiedene Klassen neu schreiben müsste, um sie in TDD verwenden zu können. Das Endergebnis ist, dass ich den Begriff schnell ganz aufgeben muss.

Es hilft wahrscheinlich nicht, dass ich oft die einzige Person in der gesamten Firma bin, die weiß, was Unit-Testing (TDD oder anders) ist und warum es eine gute Sache ist.

Wayne Molina
quelle
1
Hier kommen Mocking-Frameworks ins Spiel. Instanziieren Sie Foomit Mock- Objekten Quuxund nicht Bazdirekt. Anschließend können Sie die zu testende Funktion aufrufen und überprüfen, ob die Mocks mit den von Ihnen erwarteten Funktionen aufgerufen wurden. Mock-Objekte sind die Aktivierungstechnologie, mit der Einheiten entkoppelt und testbar gemacht werden können. Dies ist der Grund, warum Singletons böse sind, da man sie oft nicht einfach ausspotten kann. * 8 ')
Mark Booth
7

TDD-Eiferer.

Für mich sind sie nur ein Teil einer langen Reihe religiöser Spinner, die an meine Tür klopfen, um zu beweisen, dass meine Arbeitsweise irreparabel ist und der einzige Weg zur Erlösung Jesus, Kent Back oder Unit Testing ist.

IMO, ihre größte Lüge ist , dass TDD Sie führen Heil einen besseren Algorithmus Design. Sehen Sie sich den berühmten Soduku-Löser in TDD an: hier , hier , hier , hier und hier

Und vergleichen Sie es mit dem Sudoku-Löser von Peter Norvig, der nicht mit TDD, sondern mit altmodischem Engineering erstellt wurde: http://norvig.com/sudoku.html

Cesar Canassa
quelle
Schauen Sie, wir könnten uns darüber immer wieder streiten. Aber ich habe viel zu viel zu tun, da ich mit meinem Abschluss in Game Design an der Fullsail University studiert habe. Aufgrund meiner Kurse und meines sehr anspruchsvollen Jobs kann ich sagen, dass TDD die rasende Entwicklung fauler Programmierer Zeile für Zeile (mangelndes Design) übertrifft. Ich würde es nicht sagen, aber es ist wahr: Die meisten Entwickler, die ein normales Universitäts-CS-Programm besucht haben, haben zumeist keinen Abschluss gemacht, die wenigen, die überwiegend nicht in die Softwareentwicklung eingestiegen sind, und darüber hinaus kommen viele von ihnen kaum durch , Zeile für Zeile. Fullsail Universität hat eine
Zombies
Schließe den Kurs in testgetriebener Entwicklung alleine ab und das bringt Entwickler wirklich auf die richtige Spur (im Gegensatz zur Implementierung einer verknüpften Liste in c ++).
Zombies
Links sind kaputt Alter!
lmiguelvargasf
Dies ist viele Jahre später, aber @ Zombies, schauen Sie in "Confirmation Bias". Vieles von dem, was wir alle in der Schule in CS unterrichtet bekommen, fällt genau in diese Kategorie.
Werfen
Lol Mann, ich habe getrollt ... Ich habe geschrieben, dass ich dieses kleine Juwel vor so langer Zeit vergessen habe.
Zombies
5

Wenn Sie TDD aus diesen "fanatischen" Artikeln verwenden, bekommen Sie das falsche Sicherheitsgefühl, dass Ihre Software keine Fehler aufweist.

Dainius
quelle
1
Können Sie ein anderes Gefühl haben, als zu wissen, dass Ihre Software für einen bestimmten Satz von Eingaben einen bestimmten Satz von Ausgaben zurückgibt?
Solange du verstehst, dass tdd ein Entwicklungsprozess ist und keine Goldregel, um irgendwelche Probleme zu lösen, ist es in Ordnung. Aber die meisten Leute, die sich für diesen Prozess entscheiden, haben vergessen, dass es sich um einen Entwicklungsprozess handelt, und wie jeder andere Prozess hat er eine positive und eine negative Seite. Sie sagen für alle, dass, wenn Sie tdd verwenden, Sie fehlerfreie Software haben werden, weil Sie Test verwenden werden, um jede Funktion abzudecken. Und normalerweise ist es nicht richtig. Am besten wird es für jeden Fall einen Test geben (oder zumindest ein Feature), aber bei Tests handelt es sich um Programme (die Bugs haben) und es handelt sich nur um Black-Box-Tests.
Dainius
4

TDD haben einige Vorteile:

  • Sie konzentrieren sich darauf, wie Sie Ihren Code aufrufen und was Sie zuerst zu erwarten haben (wenn Sie den Test zuerst schreiben), anstatt sich auf die Lösung des Problems zu konzentrieren, und fügen dann einen Aufruf aus der Anwendung ein. Die Modularität erleichtert das Verspotten und Verpacken.
  • Die Tests stellen sicher, dass Ihr Programm vor und nach einem Refactoring gleich funktioniert. Dies bedeutet nicht, dass Ihr Programm fehlerfrei ist, sondern dass es weiterhin auf die gleiche Weise funktioniert.

Bei TDD geht es um langfristige Investitionen. Der Aufwand zahlt sich aus, wenn Sie den Wartungsmodus Ihrer Anwendung erreichen. Wenn die Anwendung nicht bis zu diesem Zeitpunkt geplant ist, können Sie die Investition möglicherweise nie zurückerhalten.

Ich betrachte den TDD-Rot-Grün-Zyklus mit den Babyschritten als eine Art Checkliste für ein Flugzeug. Es ist ärgerlich und mühsam, alles im Flugzeug vor dem Start zu überprüfen, besonders wenn es einfach ist (die TDD-Babyschritte), aber festgestellt wurde, dass es die Sicherheit erhöht. Abgesehen davon, dass überprüft wird, ob alles funktioniert, wird das Flugzeug im Wesentlichen zurückgesetzt . Mit anderen Worten, ein Flugzeug wird vor jedem Start neu gestartet.

user1249
quelle
3
Vorteil Punkt 2 kann auch mit einfachen Unit-Tests ohne TDD-Ansatz erreicht werden. Benefit 1 sollten Sie auf jeden Fall tun. (Konzentration auf die API) Es ist immer noch möglich, eine beschissene API mit TDD zu erstellen, aber Sie können sicher sein, dass dies funktioniert (für die schriftlichen Tests).
Steven Jeuris
2
Die Frage stellte sich nicht nach den Vorteilen von TDD. Es gibt bereits viele andere Fragen dazu.
Aaronaught
1
@aaronaught, ich spreche seine Schmerzpunkte an.
Antworten sollten sich mit der Frage befassen .
Aaronaught
1
@aaronaught, dann schreibe einige davon.
3

Meine negative Erfahrung mit TDD ist etwas, was ich mit vielen neuen und gehypten Sachen empfinde. Tatsächlich gefällt mir TDD, weil es die Gültigkeit meines Codes sicherstellt, und noch wichtiger: Ich kann fehlgeschlagene Tests erkennen, nachdem ich neuen Code hinzugefügt oder irgendeine Art von Refactoring durchgeführt habe.

Was mich an TDD ärgert, ist die Tatsache, dass es viele Regeln oder Richtlinien gibt. Da es noch ziemlich neu ist, erleben wir die meisten von uns als Anfänger bei TDD. Was für einige von uns gut funktioniert, funktioniert für andere vielleicht nicht. Was ich sagen möchte, ist, dass es keinen wirklichen "falschen oder richtigen" Weg gibt, TDD durchzuführen: Es gibt den Weg, der für mich funktioniert - und mein Team, wenn ich einen habe.

So lange Sie Tests schreiben - bevor oder nachdem der Produktionscode keine Rolle spielt - bin ich mir nicht sicher, ob Testfahrten wirklich bedeuten, dass Sie alle Richtlinien befolgen müssen, die im Moment angegeben sind, da sie noch nicht bewiesen sind die ideale lösung für den arbeitsalltag. Wenn Sie beim Schreiben von Tests einen besseren Weg finden, sollten Sie ihn in einem Blog veröffentlichen, hier diskutieren oder einen Artikel darüber schreiben. In ungefähr zehn Jahren haben wir möglicherweise genug Erfahrungen ausgetauscht, um feststellen zu können, welche TDD-Regel in einer bestimmten Situation als gut oder nicht gut angesehen werden kann.

Alex
quelle
+1 Hervorragender Kommentar. Es muss wirklich nicht der einzig wahre Weg oder gar kein Weg sein.
unpythonic
3

Ich habe mehr als einmal Code geschrieben, den ich am nächsten Tag verwarf, da er unbeholfen war. Ich habe mit TDD neu gestartet und die Lösung war besser. Ich hatte also nicht zu viel negative TDD-Erfahrung. Trotzdem habe ich über ein Problem nachgedacht und mir eine bessere Lösung außerhalb des TDD-Bereichs ausgedacht.

user23356
quelle
1
Normalerweise gibt Ihnen ein zweiter Versuch mehr Einblicke in das Problem als der erste Versuch, ob TDD oder nicht.
wobbily_col
3

Ich habe festgestellt, dass TDD bei aufstrebenden Systemen schlechte Leistungen erbringt. Ich bin ein Videospielentwickler und habe TDD kürzlich verwendet, um ein System zu erstellen, das mehrere einfache Verhaltensweisen verwendet, um eine realistisch aussehende Bewegung für eine Entität zu erstellen.

Es gibt zum Beispiel Verhaltensweisen, die dafür verantwortlich sind, Sie von gefährlichen Bereichen unterschiedlicher Art zu entfernen, und Verhaltensweisen, die dafür verantwortlich sind, Sie zu interessanten Bereichen unterschiedlicher Art zu bewegen. Durch die Zusammenführung der Ergebnisse der einzelnen Verhaltensweisen entsteht eine endgültige Bewegung.

Die Eingeweide des Systems ließen sich leicht implementieren, und TDD war hier nützlich, um anzugeben, wofür jedes Subsystem verantwortlich sein sollte.

Ich bekam jedoch Probleme, wenn es darum ging zu spezifizieren, wie die Verhaltensweisen interagieren, und was noch wichtiger ist, wie sie sich im Laufe der Zeit gegenseitig beeinflussen. Oft gab es keine richtige Antwort, und obwohl meine ersten Tests bestanden wurden, konnte die Qualitätssicherung immer wieder Fälle finden, in denen das System nicht funktionierte. Um die richtige Lösung zu finden, musste ich mehrere unterschiedliche Verhaltensweisen durchlaufen. Wenn ich die Tests jedes Mal aktualisiert habe, um die neuen Verhaltensweisen zu berücksichtigen, bevor ich überprüft habe, ob sie im Spiel funktioniert haben, habe ich die Tests möglicherweise immer wieder verworfen. Also habe ich diese Tests gelöscht.

Möglicherweise hätte ich stärkere Tests durchführen müssen, die die von der Qualitätssicherung entdeckten Randfälle erfasst haben. Wenn Sie jedoch ein System wie dieses haben, das auf vielen Physik- und Gameplay-Systemen aufbaut und mit den Verhaltensweisen im Laufe der Zeit zu tun hat, wird es zu einem kleinen Problem Alptraum, um genau anzugeben, was passiert.

Ich habe mit ziemlicher Sicherheit Fehler in meiner Herangehensweise gemacht, und wie ich bereits sagte, hat TDD hervorragend funktioniert und sogar einige optimierende Refaktoren unterstützt.

Tenpn
quelle