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).
Antworten:
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.
quelle
Dieses ( Clojure- Autor) Rich Hickey-Interview enthält Folgendes. Ich fühle mich 100% sympathisch:
Eine weitere ähnliche Aussage von Donald Knuth in Coders at Work-Buchinterview , kopiert von hier :
quelle
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.
quelle
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:
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:
quelle
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.
quelle
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.
quelle
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.
quelle
Als großer Fan von TDD sehe ich manchmal diese Nachteile
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
quelle
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 :
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.
quelle
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
Foo
Objekt neu anlegen, kann ich aQuux
an das übergebenBaz
und 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.
quelle
Foo
mit Mock- ObjektenQuux
und nichtBaz
direkt. 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 ')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
Heileinen besseren Algorithmus Design. Sehen Sie sich den berühmten Soduku-Löser in TDD an: hier , hier , hier , hier und hierUnd 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
quelle
Wenn Sie TDD aus diesen "fanatischen" Artikeln verwenden, bekommen Sie das falsche Sicherheitsgefühl, dass Ihre Software keine Fehler aufweist.
quelle
TDD haben einige Vorteile:
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.
quelle
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.
quelle
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.
quelle
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.
quelle