Nachteile der testgetriebenen Entwicklung? [geschlossen]

192

Was verliere ich durch testgetriebenes Design?

Nur Negative auflisten; Nennen Sie keine negativ geschriebenen Leistungen.

IanL
quelle
Ich habe eine Antwort hinzugefügt, die besagt, dass BDD einige dieser Negative lindern kann. Ich fordere Sie dringend auf, diesen Faktor beim Sammeln Ihrer negativen Eingaben zu berücksichtigen, da ein Teil davon beseitigt werden kann und nicht mehr als negativ angesehen wird.
Kilhoffer
25
Zur Klarstellung bin ich nicht dagegen oder dafür. Ich versuche, eine fundierte Entscheidung in dieser Angelegenheit zu treffen, aber die meisten Leute, die sich für TDD einsetzen, verstehen die Negative nicht oder werden sie nicht zugeben.
IanL
1
Der Titel erwähnt "Test Driven Development", aber der Hauptteil der Frage erwähnt "Test Driven Design". Um welche der beiden geht es in dieser Frage? Es gibt wichtige, aber subtile Unterschiede zwischen den beiden. Beim testgetriebenen Design geht es darum, dass die Tests das Design der Software steuern. Testgetriebene Entwicklung ist normalerweise mit dem Schreiben von Tests vor dem Produktionscode verbunden (aber nicht unbedingt, dass Tests das Design beeinflussen).
Jim Hurne
3
TDD ist ein Käfig, der die Kreativität des Entwicklers aufhält.
Lewis
13
Bitte hören Sie auf, wichtige Fragen zu schließen, Djesus
Casper Leon Nielsen

Antworten:

129

Mehrere Nachteile (und ich behaupte nicht, dass es keine Vorteile gibt - insbesondere beim Schreiben der Grundlage eines Projekts - es würde am Ende viel Zeit sparen):

  • Große Zeitinvestition. Für den einfachen Fall verlieren Sie ungefähr 20% der tatsächlichen Implementierung, aber für komplizierte Fälle verlieren Sie viel mehr.
  • Zusätzliche Komplexität. Für komplexe Fälle sind Ihre Testfälle schwieriger zu berechnen. In solchen Fällen würde ich empfehlen, den automatischen Referenzcode zu verwenden, der in der Debug-Version / im Testlauf parallel ausgeführt wird, anstatt den Komponententest der einfachsten Fälle.
  • Auswirkungen auf das Design. Manchmal ist das Design zu Beginn nicht klar und entwickelt sich im Laufe der Zeit weiter. Dies zwingt Sie dazu, Ihren Test zu wiederholen, was zu einem großen Zeitverlust führt. Ich würde vorschlagen, Unit-Tests in diesem Fall zu verschieben, bis Sie ein gewisses Verständnis für das Design haben.
  • Kontinuierliche Optimierung. Für Datenstrukturen und Black-Box-Algorithmen wären Unit-Tests perfekt, aber für Algorithmen, die dazu neigen, geändert, optimiert oder fein abgestimmt zu werden, kann dies eine große Zeitinvestition verursachen, von der man behaupten könnte, dass sie nicht gerechtfertigt ist. Verwenden Sie es also, wenn Sie der Meinung sind, dass es tatsächlich zum System passt, und erzwingen Sie nicht, dass das Design zu TDD passt.
Adi
quelle
7
Der Hauptpunkt (4) ist - jedes System, das nicht genau definiert ist und sich wahrscheinlich ständig ändert, um sich an ein sich entwickelndes visuelles Verhalten, unterschiedliche KI-Spezifikationen, Verhaltensalgorithmen usw. anzupassen, verursacht große Investitionen in wiederholte Testdefinitionen, da wir diese beibehalten beim Ändern der gewünschten Testergebnisse.
Adi
12
Stimmt, aber wäre das ohne TDD nicht dasselbe? Ohne sie müssten Sie mehr manuelle Tests durchführen, bei denen das gleiche Problem auftreten würde.
Sleske
50
Sparen Sie nicht später durch die "große Zeitinvestition" Zeit bei der Entwicklung Ihrer Lösung? Besonders bei einem komplexen? Ich denke, es sollte dir Zeit sparen. Denken Sie nicht an die Wartungsphase, in der kleine Änderungen das System leicht beschädigen können. ( oder vielleicht bin ich nur naiv in Bezug auf Unit + Regressionstests, die zukünftige Fehler verhindern )
Robert Koritnik
6
Sergio / Robert, ich bin sehr dafür, Unit-Tests für generische Systeme und definitiv für Komponenten durchzuführen, die die Grundlage für Systeme darstellen. Trotzdem möchte ich hinzufügen, dass man zwischen diesen Fällen und einer übermäßigen Vereinfachung des wirklichen Lebens unterscheiden muss, indem man behauptet, dass jedes System auf diese Weise behandelt werden kann. Nicht alle Systeme können für Komponententests verallgemeinert und vereinfacht werden. Wenn Sie versuchen, die Art der Komponententests auf solchen Systemen zu erzwingen, können Sie leicht viel mehr Zeit damit verbringen, Ihre Komponententests zu korrigieren, als tatsächliche Ergebnisse zu testen.
Adi
3
@Adi: Ich denke, dass du falsch liegst. Meiner Meinung nach kann jedes System auf diese Weise getestet werden, es geht nur um Selbstdisziplin.
BlueLettuce16
189

Wenn Sie "echtes" TDD durchführen möchten (lesen Sie: Testen Sie zuerst mit den Schritten Rot, Grün und Refactor), müssen Sie auch Mocks / Stubs verwenden, wenn Sie Integrationspunkte testen möchten.

Wenn Sie nach einer Weile mit der Verwendung von Mocks beginnen, sollten Sie mit der Verwendung von Dependency Injection (DI) und einem IoC-Container (Inversion of Control) beginnen. Um dies zu tun, müssen Sie Schnittstellen für alles verwenden (die selbst viele Fallstricke haben).

Am Ende des Tages müssen Sie viel mehr Code schreiben, als wenn Sie es einfach auf die "einfache alte Art" tun. Anstelle einer Kundenklasse müssen Sie auch eine Schnittstelle, eine Scheinklasse, eine IoC-Konfiguration und einige Tests schreiben.

Und denken Sie daran, dass der Testcode auch gepflegt und gepflegt werden sollte. Tests sollten genauso lesbar sein wie alles andere und es braucht Zeit, um guten Code zu schreiben.

Viele Entwickler verstehen nicht ganz, wie man all dies "richtig" macht. Aber weil ihnen jeder sagt, dass TDD der einzig wahre Weg ist, Software zu entwickeln, versuchen sie einfach das Beste, was sie können.

Es ist viel schwieriger als man denkt. Oft haben Projekte, die mit TDD durchgeführt wurden, eine Menge Code, den niemand wirklich versteht. Die Unit-Tests testen oft das Falsche, den falschen Weg. Und niemand ist sich einig, wie ein guter Test aussehen soll, nicht einmal die sogenannten Gurus.

All diese Tests machen es viel schwieriger, das Verhalten Ihres Systems zu "ändern" (im Gegensatz zum Refactoring), und einfache Änderungen werden einfach zu schwierig und zeitaufwändig.

Wenn Sie die TDD-Literatur lesen, gibt es immer einige sehr gute Beispiele, aber in realen Anwendungen müssen Sie häufig über eine Benutzeroberfläche und eine Datenbank verfügen. Hier wird TDD sehr schwierig, und die meisten Quellen bieten keine guten Antworten. Und wenn doch, dann immer mehr Abstraktionen: Scheinobjekte, Programmierung auf eine Schnittstelle, MVC / MVP-Muster usw., die wiederum viel Wissen erfordern, und ... Sie müssen noch mehr Code schreiben.

Seien Sie also vorsichtig ... Wenn Sie kein begeistertes Team und mindestens einen erfahrenen Entwickler haben, der weiß, wie man gute Tests schreibt und auch ein paar Dinge über gute Architektur weiß, müssen Sie wirklich zweimal überlegen, bevor Sie den TDD-Weg gehen .

Thomas Jespersen
quelle
7
Mit Tools wie Pex & Moles können Sie ganz einfach vermeiden, Schnittstellen für jede kleine verdammte Sache zu schreiben. Maulwürfe werden Ihnen dabei enorm helfen.
Robert Koritnik
24
Scheint eine Kritik an Unit-Tests und objektorientierter Programmierung zu sein, nicht an TDD.
Plmaheu
5
Tatsächlich korrekter ** Unit-Test ** - nicht nur TDD - erfordert Mocks / Stubs. Und das Programmieren gegen eine Schnittstelle ist oft eine gute Idee, ebenso für Muster. Wenn Sie Benutzeroberfläche und Logik mischen, werden Sie eine schlechte Zeit haben. Wenn Sie die DB-Interaktion testen müssen, können Sie Ihr DAO dennoch für die Komponententests verspotten und das Original für einen Integrationstest verwenden.
TheMorph
1
Ich stimme der Tatsache zu, dass ein Nebel Kenntnisse über Design und Tests hat, bevor er zu tdd springt. Dies ist bei Projekten mit Neueinstellungen von entscheidender Bedeutung, da sie für beide neu sind.
Hitesh Sahu
stimme
66

Wenn Sie an einem Punkt angelangt sind, an dem Sie eine große Anzahl von Tests haben, müssen Sie zum Ändern des Systems möglicherweise einige oder alle Ihrer Tests neu schreiben, je nachdem, welche durch die Änderungen ungültig wurden. Dies könnte eine relativ schnelle Änderung in eine sehr zeitaufwändige ändern.

Möglicherweise treffen Sie auch Entwurfsentscheidungen, die mehr auf TDD als auf tatsächlich guten Entwurfsprinzipalen basieren. Während Sie möglicherweise eine sehr einfache Lösung hatten, mit der sich die Anforderungen von TDD nicht testen lassen, haben Sie jetzt ein viel komplexeres System, das tatsächlich anfälliger für Fehler ist.

Eric Z Bart
quelle
3
Kann definitiv ein Problem sein, aber ich sehe einen spürbaren Unterschied darin, wie sehr ich davon betroffen bin. Alles läuft darauf hinaus, "testbaren Code zu schreiben", denke ich.
Rob Cooper
2
Scott, das Beispiel, das ich normalerweise gebe, ist eine SqlDataSource, die in eine ASPX-Seite eingebettet ist. Sie können einen Test dafür nicht automatisieren. Es ist einfach und erledigt die Arbeit mit nur 1 Datei. Die testbare Komponente ist das SqlDataSource-Objekt von MSFT, und das ist bereits für uns erledigt. Wir müssen nicht mehr tun.
Eric Z Beard
8
+1 "Sie könnten anfangen, Designentscheidungen zu treffen, die mehr auf TDD als auf wirklich guten Designprinzipien basieren" - die größte Gefahr von TDD IMHO.
András Szepesházi
2
@ScottSaad das Problem IMO ist, dass das Design zuerst skizziert und dann durch Schreiben von Tests validiert und bei Bedarf korrigiert werden sollte. Ich habe zahlreiche Fälle gesehen, in denen Leute gutes Design gefährdeten, nur um Tests schreiben zu können. Infolgedessen wurde der größte Teil des Systems durch Tests abgedeckt, aber das Design war wirklich hässlich. Ich denke, dass dies geschieht, weil TDD als sehr einfache Methode mit folgendem Missverständnis in die Massen gedrängt wird : if part of the system is covered by tests and they pass, then everything is fine (including design).
Yuriy Nakonechnyy
3
@Yura: Es ist interessant, was Sie sagen, dass Leute gutes Design gefährden, nur um Tests schreiben zu können. Wenn es ein gutes Design gäbe, wäre es meiner Meinung nach nicht notwendig, es zu gefährden. Ich habe einmal ein solches Projekt gesehen und die Codebasis war ein Albtraum, aber die Leute dachten das gleiche - dass das Design großartig ist. Ich stimme nur dem Teil zu, dass TDD als sehr einfache Methode in die Massen gedrängt wird, aber es ist genau das Gegenteil. Meiner Meinung nach gibt es keine Chance, alle Tests oder große Mengen davon zu bremsen, wenn der Code gut gestaltet ist und wenn Sie eine kleine Änderung vornehmen.
BlueLettuce16
54

Ich denke, das größte Problem für mich ist der RIESIGE Zeitverlust, den ich brauche, um mich darauf einzulassen. Ich bin noch sehr am Anfang meiner Reise mit TDD (siehe mein Blog für Updates meiner Testabenteuer, wenn Sie interessiert sind) und ich habe buchstäblich Stunden verbracht , loszulegen.

Es dauert lange, bis Ihr Gehirn in den "Testmodus" wechselt, und das Schreiben von "testbarem Code" ist eine Fähigkeit für sich.

TBH, ich bin mit Respekt nicht einverstanden Jason Cohens Kommentaren zur Veröffentlichung privater Methoden , darum geht es nicht. Ich habe in meiner neuen Arbeitsweise nicht mehr öffentliche Methoden angewendet als zuvor . Es beinhaltet jedoch Änderungen an der Architektur und ermöglicht es Ihnen, Codemodule "Hot Plug" zu machen, um alles andere einfacher zu testen. Das solltest du nicht die Interna des Codes besser zugänglich werden machen , dies zu tun. Ansonsten sind wir wieder auf dem ersten Platz, da alles öffentlich ist. Wo ist die Verkapselung darin?

Also, (IMO) auf den Punkt gebracht:

  • Die Zeit, die zum Nachdenken benötigt wird (dh tatsächlich Tests durchgeführt) ).
  • Das neue Wissen, das erforderlich ist, um testbaren Code zu schreiben.
  • Verständnis der Architekturänderungen, die erforderlich sind, um Code testbar zu machen.
  • Verbessere deine Fähigkeiten als "TDD-Coder", während du versuchst, alle anderen Fähigkeiten zu verbessern, die für unser großartiges Programmierhandwerk erforderlich sind :)
  • Organisieren Sie Ihre Codebasis so, dass sie Testcode enthält, ohne Ihren Produktionscode zu beschädigen.

PS: Wenn Sie Links zu Positiven wünschen, habe ich mehrere Fragen dazu gestellt und beantwortet. Schauen Sie sich mein Profil an .

Rob Cooper
quelle
1
Leider die erste vernünftige Antwort, die ich sah ...
Daniel C. Sobral
5
Ganz praktische und einfache Antwort - +1 für den Teil "Mind Setting"
ha9u63ar
50

In den wenigen Jahren, in denen ich Test Driven Development praktiziert habe, muss ich sagen, dass die größten Nachteile sind:

Verkauf an das Management

TDD wird am besten paarweise durchgeführt. Zum einen ist es schwierig, dem Drang zu widerstehen, nur die Implementierung zu schreiben, wenn Sie wissen, wie man ein if / else schreibt Anweisung . Aber ein Paar wird Sie auf dem Laufenden halten, weil Sie ihn auf dem Laufenden halten. Leider glauben viele Unternehmen / Manager nicht, dass dies ein guter Ressourceneinsatz ist. Warum für zwei Personen bezahlen, um eine Funktion zu schreiben, wenn ich zwei Funktionen habe, die gleichzeitig ausgeführt werden müssen?

Verkauf an andere Entwickler

Einige Leute haben einfach nicht die Geduld, Unit-Tests zu schreiben. Einige sind sehr stolz auf ihre Arbeit. Oder manche sehen einfach, wie verschlungene Methoden / Funktionen am Ende des Bildschirms ausbluten. TDD ist nicht jedermanns Sache, aber ich wünschte wirklich, es wäre so. Es würde den armen Seelen, die Code erben, die Pflege von Dingen so viel einfacher machen.

Pflege des Testcodes zusammen mit Ihrem Produktionscode

Im Idealfall werden Ihre Tests nur dann unterbrochen, wenn Sie eine schlechte Codeentscheidung treffen. Das heißt, Sie dachten, das System funktioniert in eine Richtung, und es stellte sich heraus, dass dies nicht der Fall war. Wenn Sie einen Test oder eine (kleine) Reihe von Tests abbrechen, sind dies tatsächlich gute Nachrichten. Sie wissen genau, wie sich Ihr neuer Code auf das System auswirkt. Wenn Ihre Tests jedoch schlecht geschrieben, eng gekoppelt oder, noch schlimmer, erzeugt sind ( Husten) VS-Test), kann die Aufrechterhaltung Ihrer Tests schnell zu einem Chor werden. Und wenn genügend Tests mehr Arbeit verursachen als der wahrgenommene Wert, den sie schaffen, werden die Tests als erstes gelöscht, wenn Zeitpläne komprimiert werden (z. B. wenn die Zeit knapp wird).

Schreiben von Tests, damit Sie alles abdecken (100% Codeabdeckung)

Wenn Sie sich an die Methodik halten, wird Ihr Code im Idealfall standardmäßig zu 100% getestet. Normalerweise habe ich eine Codeabdeckung von über 90%. Dies passiert normalerweise, wenn ich eine Architektur im Vorlagenstil habe und die Basis getestet wird und ich versuche, Ecken zu schneiden und die Vorlagenanpassungen nicht zu testen. Außerdem habe ich festgestellt, dass ich beim Testen einer neuen Barriere, auf die ich zuvor noch nicht gestoßen war, eine Lernkurve beim Testen habe. Ich gebe zu, einige Codezeilen auf die alte Art und Weise zu schreiben, aber ich mag es wirklich, wenn ich das zu 100% habe. (Ich glaube, ich war ein Überflieger in der Schule, ähm Schule).

Damit würde ich jedoch sagen, dass die Vorteile von TDD die Nachteile für die einfache Idee bei weitem überwiegen, dass Sie es tun werden, wenn Sie eine gute Reihe von Tests erzielen können, die Ihre Anwendung abdecken, aber nicht so zerbrechlich sind, dass eine Änderung sie alle bricht Sie können an Tag 300 Ihres Projekts immer wieder neue Funktionen hinzufügen, wie Sie es an Tag 1 getan haben. Dies passiert nicht bei allen, die TDD ausprobieren und glauben, es sei ein Wundermittel für all ihren fehlerbehafteten Code, und sie glauben, dass dies möglich ist funktioniert nicht, Punkt.

Persönlich habe ich festgestellt, dass ich mit TDD einfacheren Code schreibe, weniger Zeit damit verbringe, darüber zu debattieren, ob eine bestimmte Codelösung funktioniert oder nicht, und dass ich keine Angst habe, eine Codezeile zu ändern, die die von festgelegten Kriterien nicht erfüllt Die Mannschaft.

TDD ist eine schwierige Disziplin, und ich bin seit einigen Jahren dabei und lerne immer wieder neue Testtechniken. Es ist eine enorme Zeitinvestition im Voraus, aber auf lange Sicht wird Ihre Nachhaltigkeit viel größer sein, als wenn Sie keine automatisierten Komponententests hätten. Wenn nur meine Chefs das herausfinden könnten.

casademora
quelle
7
Was war der Rest des Satzes, der mit "(Husten VS Test), dann Haupt" endete?
Andrew Grimm
+1 für das Verkaufsproblem. :) Ich bin gerade in einem neuen Unternehmen und denke darüber nach, wie ich eine Kultur schaffen kann, in der sich Fähigkeiten frei verbreiten können.
Esko Luontola
2
Wie Sie meinen, nutzen einige Beratungsunternehmen die Paarprogrammierung und TDD, um mehr Geld von ihren Kunden zu erhalten. Es ist ziemlich enttäuschend, wie diese Kunden für Ideen bezahlen, die auf den ersten Blick vernünftig erscheinen, wie z. B. zwei Leute denken viel besser als zwei oder dass TDD sicherstellt, dass jede Codezeile getestet wird, aber am Ende sind sie nur Ausreden, um einen Kunden bezahlen zu lassen mehr für etwas, das nur eine Person tun kann.
lmiguelvargasf
24

Bei Ihrem ersten TDD-Projekt gibt es zwei große Verluste: Zeit und persönliche Freiheit

Sie verlieren Zeit, weil:

  • Die Erstellung einer umfassenden, überarbeiteten und wartbaren Suite von Einheiten- und Abnahmetests verlängert die erste Iteration des Projekts erheblich. Dies kann auf lange Sicht Zeit sparen, aber auch Zeit, die Sie nicht sparen müssen.
  • Sie müssen einen Kernsatz von Tools auswählen und Experten dafür werden. Ein Unit-Test-Tool muss durch eine Art Verspottungs-Framework ergänzt werden und beide müssen Teil Ihres automatisierten Build-Systems werden. Sie möchten auch geeignete Metriken auswählen und generieren.

Sie verlieren die persönliche Freiheit, weil:

  • TDD ist eine sehr disziplinierte Art, Code zu schreiben, die dazu neigt, sich an denen oben und unten auf der Skills-Skala zu reiben. Wenn Sie den Produktionscode immer auf eine bestimmte Art und Weise schreiben und Ihre Arbeit einer kontinuierlichen Begutachtung unterziehen, kann dies Ihre schlechtesten und besten Entwickler ausflippen lassen und sogar zum Verlust der Mitarbeiterzahl führen.
  • Die meisten agilen Methoden, die TDD einbetten, erfordern, dass Sie kontinuierlich mit dem Kunden darüber sprechen, was Sie erreichen möchten (in dieser Geschichte / an diesem Tag / was auch immer) und welche Kompromisse bestehen. Auch dies ist nicht jedermanns Sache, sowohl auf der Entwicklerseite des Zauns als auch bei den Kunden.

Hoffe das hilft

Garth Gilmour
quelle
1
Ich weiß nicht, ob es daran liegt, dass ich am schlechtesten oder am besten bin. Aber TDD reibt mich falsch. Das liegt daran, dass ich zu früh in den dualen Wartungsmodus gezwungen werde. Jedes Mal, wenn ich das Design einer Klasse ändere, muss ich jetzt auch die Testfälle ändern. Ich erwarte und akzeptiere das von einer reifen Klasse, aber nicht von einer Klasse, die ich letzte Woche geschrieben habe! Ich kann auch nur sagen, dass DI und TDD von Sprachen wie Java und C # nicht gut unterstützt werden. Jemand muss wirklich eine neue Sprache erstellen, damit die Kosten für TDD und DI buchstäblich Null sind . Dann werden wir dieses Gespräch nicht mehr führen.
John Henckel
14

Bei TDD müssen Sie planen, wie Ihre Klassen funktionieren, bevor Sie Code schreiben, um diese Tests zu bestehen. Dies ist sowohl ein Plus als auch ein Minus.

Es fällt mir schwer, Tests in einem "Vakuum" zu schreiben - bevor Code geschrieben wurde. Nach meiner Erfahrung neige ich dazu, über meine Tests zu stolpern, wenn ich beim Schreiben meiner Klassen unweigerlich an etwas denke, das ich beim Schreiben meiner ersten Tests vergessen habe. Dann ist es Zeit, nicht nur meine Klassen, sondern auch meine Tests umzugestalten. Wiederholen Sie dies drei oder vier Mal und es kann frustrierend werden.

Ich ziehe es vor, zuerst einen Entwurf meiner Klassen zu schreiben und dann eine Reihe von Unit-Tests zu schreiben (und zu warten). Nachdem ich einen Entwurf habe, funktioniert TDD gut für mich. Wenn beispielsweise ein Fehler gemeldet wird, schreibe ich einen Test, um diesen Fehler auszunutzen, und behebe dann den Code, damit der Test erfolgreich ist.

Chrass
quelle
1
Während Sie eine Vorstellung davon haben sollten, wie die Architektur Ihres Systems aussehen wird, müssen Sie bei TDD nicht viel im Voraus wissen. TDD bedeutet, dass die Tests das Design
antreiben
4
Ich stimme dem Vakuum zu. Die ursprünglichen Tutorials von TDD, in denen Sie den Test ohne JEDEN Code schreiben und einen Kompilierungsfehler erhalten, sind verrückt.
Mparaz
Es ist eine falsche Annahme, dass Sie die Tests einmal schreiben und nicht ändern können. Sie sind Code und jeder Code erfordert ein eventuelles Refactoring, nachdem Sie Änderungen vorgenommen haben. Tests sind keine Ausnahme. Refactoring-Tests sind ein Muss, wenn Sie sie wartbar halten möchten.
Roman Konoval
12

Prototyping kann mit TDD sehr schwierig sein. Wenn Sie sich nicht sicher sind, welchen Weg Sie zu einer Lösung einschlagen sollen, kann es schwierig sein, die Tests im Voraus zu schreiben (außer bei sehr umfassenden). Dies kann ein Schmerz sein.

Ehrlich gesagt glaube ich nicht, dass es für die "Kernentwicklung" bei der überwiegenden Mehrheit der Projekte einen wirklichen Nachteil gibt; Es wird viel mehr geredet, als es sein sollte, normalerweise von Leuten, die glauben, dass ihr Code gut genug ist, dass sie keine Tests benötigen (es ist nie so), und von Leuten, die einfach nicht die Mühe haben, sie zu schreiben.

Calum
quelle
9

Nun, und diese Dehnung müssen Sie Ihre Tests debuggen. Es gibt auch einen gewissen Zeitaufwand für das Schreiben der Tests, obwohl die meisten Leute der Meinung sind, dass es sich um eine Vorabinvestition handelt, die sich über die Lebensdauer der Anwendung sowohl beim zeitsparenden Debuggen als auch bei der Stabilität auszahlt.

Das größte Problem, das ich persönlich damit hatte, ist es, die Disziplin aufzubauen, um die Tests tatsächlich zu schreiben. In einem Team, insbesondere in einem etablierten Team, kann es schwierig sein, sie davon zu überzeugen, dass sich die aufgewendete Zeit lohnt.

Tim Sullivan
quelle
13
Aha - aber hier kommt TDTDD ins Spiel. Test Driven Test Driven Development.
Snowcrash
3
Ich finde immer noch gelegentlich Fehler in meinen Testtests. Jetzt übe ich TDTDTDD.
HorseloverFat
@SnowCrash +1 Ich habe mich bei Google umgesehen, um zu sehen, wie viel Zeit die Leute damit verbringen, ihre Tests zu testen, und dann habe ich diese Antwort gesehen. Ich habe das offiziell gefunden, weil ich mich über TDTDTDD gewundert habe.
BalinKingOfMoria CMs
1
Ich glaube, die Zukunft ist (TD) <sup> ∞ </ sup> TDD. Ich habe bisher eine Datei: Sie enthält den Buchstaben "x".
Mike Nagetier
Ich stimme @Tim zu. Die Mitglieder davon zu überzeugen, es anzunehmen, ist der schwierigste Teil.
Olu Smith
7

Wenn Ihre Tests nicht sehr gründlich sind, könnten Sie in ein falsches Gefühl von "alles funktioniert" geraten, nur weil Sie die Tests bestehen. Theoretisch funktioniert der Code, wenn Ihre Tests bestanden wurden. Aber wenn wir beim ersten Mal perfekt Code schreiben könnten, bräuchten wir keine Tests. Die Moral hier ist, sicherzustellen, dass Sie selbst eine Überprüfung der geistigen Gesundheit durchführen, bevor Sie etwas Vollständiges anrufen. Verlassen Sie sich nicht nur auf die Tests.

In diesem Sinne, wenn Ihre Überprüfung der geistigen Gesundheit etwas findet, das nicht getestet wurde, gehen Sie zurück und schreiben Sie einen Test dafür.

Aaron Lee
quelle
Ich glaube nicht an eine Vernunftklausel, seit ich aufgewachsen bin.
Mike Nagetier
7

Der Nachteil von TDD ist, dass es normalerweise eng mit der 'Agile'-Methodik verbunden ist Dokumentation eines Systems keine Rolle spielt, sondern das Verständnis, warum ein Test einen bestimmten Wert zurückgeben sollte, anstatt dass irgendein anderer nur beim Entwickler liegt Kopf.

Sobald der Entwickler den Grund verlässt oder vergisst, dass der Test einen bestimmten Wert und keinen anderen zurückgibt, sind Sie fertig. TDD ist in Ordnung, wenn es angemessen dokumentiert und von einer lesbaren Dokumentation (dh einem spitzen Manager) umgeben ist, auf die in 5 Jahren verwiesen werden kann, wenn sich die Welt ändert und Ihre App dies auch muss.

Wenn ich von Dokumentation spreche, ist dies kein Klappentext im Code, sondern eine offizielle Schrift, die außerhalb der Anwendung existiert, wie z. B. Anwendungsfälle und Hintergrundinformationen, auf die Manager, Anwälte und der arme Kerl, der aktualisiert werden muss, verweisen können Ihr Code im Jahr 2011.

Ron McMahon
quelle
1
Perfekt ausgedrückt. Ich konnte nicht mehr zustimmen. Für mich helfen Tests sicherlich nicht dabei, reale, übergeordnete Problemdefinitionen zu beschreiben. Gute Dokumentation hat sich immer wieder bewährt. Wie die Technik. In der Industrie sollten bewährte Begriffe immer sorgfältiger verwendet werden. Selbstdokumentierender Code ist eine lächerliche Vorstellung. Ich glaube an Prototyping, Refactoring und die Agilität, ein Problem zu Beginn nie zu definieren. Ironischerweise macht es das Stubbing für TDD zu einem Minenfeld, wenn das Problem zu Beginn nicht überdefiniert wird.
Wax_lyrical
1
Ich finde das unfair. Gute TDD-Praktiken verurteilen magische Zahlen und obskure Tests. Tests sollten einfach und besser oder besser lesbar sein als Ihr Produktionscode. Ihre Tests sind die Dokumentation. Stellen Sie sicher, dass sie so aussehen. Diese Antwort fühlt sich ein bisschen so an, als würde man sagen "Dokumentation ist böse, weil manchmal Leute wirklich schlechte Dokumentation schreiben" oder "Klassen sind schlecht, weil ich einige Gottklassen gesehen habe, mit denen man nur schwer umgehen konnte".
Sara
6

Ich habe mehrere Situationen erlebt, in denen TDD mich verrückt macht. Um einige zu nennen:

  • Wartbarkeit des Testfalls:

    Wenn Sie in einem großen Unternehmen tätig sind, besteht die Möglichkeit, dass Sie die Testfälle nicht selbst schreiben müssen oder zumindest die meisten davon von jemand anderem geschrieben werden, wenn Sie in das Unternehmen eintreten. Die Funktionen einer Anwendung ändern sich von Zeit zu Zeit. Wenn Sie kein System wie das HP Quality Center haben, um sie zu verfolgen, werden Sie in kürzester Zeit verrückt.

    Dies bedeutet auch, dass neue Teammitglieder ziemlich viel Zeit benötigen, um zu erfahren, was mit den Testfällen los ist. Dies kann wiederum dazu führen, dass mehr Geld benötigt wird.

  • Komplexität der Testautomatisierung:

    Wenn Sie einige oder alle Testfälle in maschinenlaufbare Testskripte automatisieren, müssen Sie sicherstellen, dass diese Testskripte mit den entsprechenden manuellen Testfällen synchron sind und den Anwendungsänderungen entsprechen.

    Außerdem verbringen Sie Zeit damit, die Codes zu debuggen, mit denen Sie Fehler erkennen können. Meiner Meinung nach sind die meisten dieser Fehler darauf zurückzuführen, dass das Testteam die Anwendungsänderungen im Automatisierungstestskript nicht berücksichtigt hat. Änderungen in der Geschäftslogik, der Benutzeroberfläche und anderen internen Dingen können dazu führen, dass Ihre Skripte nicht mehr oder nicht mehr zuverlässig ausgeführt werden. Manchmal sind die Änderungen sehr subtil und schwer zu erkennen. Einmal meldeten alle meine Skripte einen Fehler, weil sie ihre Berechnung auf Informationen aus Tabelle 1 basierten, während Tabelle 1 jetzt Tabelle 2 war (weil jemand den Namen der Tabellenobjekte im Anwendungscode ausgetauscht hatte).

Martin08
quelle
Dies betrifft TDD überhaupt nicht. Wenn jemand anderes in einer anderen Abteilung Ihre Testfälle schreibt, führen Sie keine TDD durch. Wenn Sie manuelle Testfälle haben, führen Sie keine TDD durch. Wenn Ihr Bibliothekscode kaputt geht und Ihre Tests aufgrund von Änderungen an der Benutzeroberfläche fehlschlagen, führen Sie höchstwahrscheinlich auch kein TDD durch. Dies scheint eher ein Argument gegen große ineffektive QS-Abteilungen von Unternehmen zu sein.
Sara
5

Das größte Problem sind die Leute, die nicht wissen, wie man richtige Unit-Tests schreibt. Sie schreiben Tests, die voneinander abhängen (und sie funktionieren hervorragend mit Ant, aber dann scheitern sie plötzlich, wenn ich sie von Eclipse aus ausführe, nur weil sie in unterschiedlicher Reihenfolge ausgeführt werden). Sie schreiben Tests, die nichts Besonderes testen - sie debuggen einfach den Code, überprüfen das Ergebnis und ändern ihn in Test, indem sie ihn "test1" nennen. Sie erweitern den Umfang der Klassen und Methoden, nur weil es einfacher sein wird, Unit-Tests für sie zu schreiben. Der Code von Unit-Tests ist schrecklich, mit all den klassischen Programmierproblemen (starke Kopplung, Methoden mit einer Länge von 500 Zeilen, hartcodierten Werten, Codeduplizierung) und eine Hölle, die es zu pflegen gilt. Aus irgendeinem seltsamen Grund behandeln Leute Unit-Tests als etwas, das dem "echten" Code unterlegen ist, und sie tun es nicht. Ich kümmere mich überhaupt nicht um ihre Qualität. :-(

rmaruszewski
quelle
4

Sie verlieren viel Zeit damit, Tests zu schreiben. Dies könnte natürlich bis zum Ende des Projekts gespeichert werden, indem Fehler schneller erkannt werden.

Joel Coehoorn
quelle
Ist das wirklich eine negative oder schlaue Art, ein Positives zu sagen?
IanL
3

Der größte Nachteil ist, dass Sie viel scheitern müssen, wenn Sie TDD wirklich richtig machen wollen, bevor Sie Erfolg haben. Wenn man bedenkt, wie viele Softwareunternehmen arbeiten (Dollar pro KLOC), werden Sie schließlich entlassen. Selbst wenn Ihr Code schneller, sauberer, einfacher zu warten und weniger Fehler aufweist.

Wenn Sie in einem Unternehmen arbeiten, das Sie durch die KLOCs bezahlt (oder die implementierten Anforderungen - auch wenn sie nicht getestet wurden), halten Sie sich von TDD (oder Codeüberprüfungen oder Paarprogrammierung oder kontinuierlicher Integration usw. usw. usw.) fern.

Vasco Duarte
quelle
3

Sie verlieren die Fähigkeit zu sagen, dass Sie "fertig" sind, bevor Sie Ihren gesamten Code testen.

Sie verlieren die Fähigkeit, Hunderte oder Tausende von Codezeilen zu schreiben, bevor Sie sie ausführen.

Sie verlieren die Möglichkeit, durch Debuggen zu lernen.

Sie verlieren die Flexibilität, Code zu versenden, dessen Sie sich nicht sicher sind.

Sie verlieren die Freiheit, Ihre Module eng zu koppeln.

Sie verlieren die Möglichkeit, das Schreiben von Konstruktionsdokumentationen auf niedriger Ebene zu überspringen.

Sie verlieren die Stabilität, die mit Code einhergeht, den jeder fürchten muss.

Onkel Bob
quelle
1
Hängt von Ihrer Definition von "pünktlich eine Lösung liefern" ab - ist das "jede alte, teilweise defekte Lösung pünktlich" oder "pünktlich funktionierende Lösungen liefern". Sie verlieren sicherlich die Fähigkeit, teilweise defekte Lösungen pünktlich zu liefern. Was die Geschwindigkeit der Entwickler angeht, gefällt mir die Metrik "Verstrichene Zeit zwischen dem Start der Entwicklung und einer Woche fehlerfreier Live-Bereitstellung". Wenn Sie es fair messen, ist es schwierig, die Uhr auf einem Copmlex-Stück Nicht-TDD-Werk überhaupt anzuhalten.
Dafydd Rees
47
-1, das ist genau das, was der OP gesagt hat, dass er nicht wollte.
Erikkallen
1
Viele wahre Aussagen, aber: was erikkallen gesagt hat. -1.
j_random_hacker
@ j_random_hacker sagt Hacker ... LOL
Dan
nur die dritte Aussage ist legitim "Lernen durch Debuggen ist verloren"
YEH
2

Ich stimme der Antwort über die anfängliche Entwicklungszeit zu. Sie verlieren auch die Fähigkeit, bequem ohne die Sicherheit von Tests zu arbeiten. Ich wurde auch als TDD-Nutbar beschrieben, sodass du ein paar Freunde verlieren könntest;)

Chris Canal
quelle
2

Es wird als langsamer wahrgenommen. Langfristig ist das nicht wahr in Bezug auf die Trauer, die Sie später retten werden, aber Sie werden am Ende mehr Code schreiben, so dass Sie wahrscheinlich Zeit damit verbringen, "nicht zu codieren" zu testen. Es ist ein fehlerhaftes Argument, aber Sie haben gefragt!

MarcE
quelle
2

Sich auf schwierige, unvorhergesehene Anforderungen zu konzentrieren, ist der ständige Fluch des Programmierers. Testgetriebene Entwicklung zwingt Sie, sich auf die bereits bekannten, alltäglichen Anforderungen zu konzentrieren, und beschränkt Ihre Entwicklung auf das, was Sie sich bereits vorgestellt haben.

Denken Sie darüber nach, es ist wahrscheinlich, dass Sie bestimmte Testfälle entwerfen, sodass Sie nicht kreativ werden und denken: "Es wäre cool, wenn der Benutzer X, Y und Z ausführen könnte." Wenn sich dieser Benutzer über die möglichen coolen Anforderungen X, Y und Z aufregt, ist Ihr Design möglicherweise zu stark auf bereits festgelegte Testfälle ausgerichtet, und es ist schwierig, sie anzupassen.

Dies ist natürlich ein zweischneidiges Schwert. Wenn Sie Ihre ganze Zeit damit verbringen, für jedes denkbare, vorstellbare X, Y und Z zu entwerfen, das ein Benutzer jemals haben möchte, werden Sie unweigerlich nie etwas fertigstellen. Wenn Sie etwas vervollständigen, kann niemand (einschließlich Sie selbst) eine Vorstellung davon haben, was Sie in Ihrem Code / Design tun.

Doug T.
quelle
Denken Sie darüber nach, es ist wahrscheinlich, dass Sie bestimmte Testfälle entwerfen, sodass Sie nicht kreativ werden und denken: "Es wäre cool, wenn der Benutzer X, Y und Z ausführen könnte." - Meiner Meinung nach ist das genau das Gegenteil. Wenn Sie Unit-Tests schreiben, wundern Sie sich über verschiedene Geschäftsfälle. Das bedeutet, dass Sie kreativ sind und etwas Unvorhergesehenes vorhersehen können. All diese Kreativität ist jedoch nicht wichtig, wenn Ihre Implementierung Fehler aufweist.
BlueLettuce16
1

Das Schreiben von Tests für "zufällige" Daten wie XML-Feeds und Datenbanken kann schwierig und zeitaufwändig sein (nicht so schwierig). Ich habe in letzter Zeit einige Zeit damit verbracht, mit Wetterdaten-Feeds zu arbeiten. Es ist ziemlich verwirrend, Tests dafür zu schreiben, zumindest weil ich nicht zu viel Erfahrung mit TDD habe.

Vargen
quelle
Dies ist ein häufiges Problem. Ich neige dazu, diese mit hartcodierten Objekten zu verspotten und dann die Datenbank separat zu testen. Ihre Business-Schicht sollte dann nur mit statischen Daten arbeiten. Ihr DAL wird dann in einer kontrollierten Umgebung getestet (in der Sie die Daten skripten können usw.)
Rob Cooper,
1

Sie verlieren große Klassen mit mehreren Verantwortlichkeiten. Sie werden wahrscheinlich auch große Methoden mit mehreren Verantwortlichkeiten verlieren. Möglicherweise verlieren Sie die Fähigkeit zur Umgestaltung, aber Sie verlieren auch einen Teil der Notwendigkeit zur Umgestaltung.

Jason Cohen sagte so etwas wie: TDD erfordert eine bestimmte Organisation für Ihren Code. Dies könnte architektonisch falsch sein; Da private Methoden beispielsweise nicht außerhalb einer Klasse aufgerufen werden können, müssen Sie Methoden nicht privat machen, um sie testbar zu machen.

Ich sage, dies deutet auf eine fehlende Abstraktion hin. Wenn der private Code wirklich getestet werden muss, sollte er sich wahrscheinlich in einer separaten Klasse befinden.

Dave Mann

Dave Mann
quelle
1

Sie müssen Anwendungen auf eine andere Art und Weise schreiben: eine, die sie testbar macht. Sie wären überrascht, wie schwierig dies zunächst ist.

Einige Leute finden das Konzept, darüber nachzudenken, was sie schreiben werden, bevor sie es zu schwer schreiben. Konzepte wie Spott können auch für manche schwierig sein. TDD in Legacy-Apps kann sehr schwierig sein, wenn sie nicht zum Testen entwickelt wurden. TDD um Frameworks, die nicht TDD-freundlich sind, kann ebenfalls ein Kampf sein.

TDD ist eine Fähigkeit, mit der Junior-Entwickler zunächst Schwierigkeiten haben können (hauptsächlich, weil ihnen nicht beigebracht wurde, auf diese Weise zu arbeiten).

Insgesamt werden die Nachteile jedoch gelöst, wenn die Leute kompetent werden und Sie am Ende den "stinkenden" Code abstrahieren und ein stabileres System haben.

Peter Gillard-Moss
quelle
1

Es dauert einige Zeit, um sich darauf einzulassen, und einige Zeit, um in einem Projekt damit zu beginnen, aber ... Ich bedauere immer, dass ich keinen testgetriebenen Ansatz gewählt habe, wenn ich dumme Fehler finde, die ein automatisierter Test sehr schnell hätte finden können. Darüber hinaus verbessert TDD die Codequalität.

aerlijman
quelle
1
  • Unit-Tests sind mehr Code zu schreiben, daher höhere Vorab-Entwicklungskosten
  • Es ist mehr Code zu pflegen
  • zusätzliches Lernen erforderlich
Bob Dizzle
quelle
1

Gute Antworten alle. Ich würde ein paar Möglichkeiten hinzufügen, um die dunkle Seite von TDD zu vermeiden:

  • Ich habe Apps geschrieben, um ihren eigenen randomisierten Selbsttest durchzuführen. Das Problem beim Schreiben spezifischer Tests besteht darin, dass selbst wenn Sie viele davon schreiben, diese nur die Fälle abdecken, an die Sie denken. Zufallstestgeneratoren finden Probleme, an die Sie nicht gedacht haben.

  • Das gesamte Konzept vieler Komponententests impliziert, dass Sie Komponenten haben, die in ungültige Zustände geraten können, z. B. komplexe Datenstrukturen. Wenn Sie sich von komplexen Datenstrukturen fernhalten, müssen Sie viel weniger testen.

  • Wenn Ihre Anwendung dies zulässt, sollten Sie sich vor einem Design scheuen, das auf der richtigen Reihenfolge von Benachrichtigungen, Ereignissen und Nebenwirkungen beruht. Diese können leicht fallen gelassen oder durcheinander gebracht werden, so dass sie viele Tests benötigen.

Mike Dunlavey
quelle
Zufällige Tests können zeitweise fehlschlagen und das Wiederholen erschweren
David Sykes
@DavidSykes: Wenn Sie einen zufälligen Test durchführen, zeichnen Sie die Parameter auf, sodass Sie ihn bei einem Fehler wiederholen oder später wiederholen können, auch wenn er nicht fehlgeschlagen ist. Der Punkt ist, dass es nicht von Ihnen abhängt, sich die Testfälle auszudenken. Wenn Sie wie ich sind, tendieren Sie instinktiv zu sicheren Testfällen.
Mike Dunlavey
0

TDD erfordert eine bestimmte Organisation für Ihren Code. Dies kann ineffizient oder schwer zu lesen sein. Oder sogar architektonisch falsch; zum Beispiel seitprivate Methoden nicht außerhalb einer Klasse aufgerufen werden können, müssen Sie Methoden nicht privat machen, um sie testbar zu machen, was einfach falsch ist.

Wenn sich der Code ändert, müssen Sie auch die Tests ändern. Mit Refactoring kann dies eine Menge zusätzlicher Arbeit sein.

Jason Cohen
quelle
9
Alle privaten Methoden sollten mit den ohnehin vorhandenen öffentlichen Methoden getestet werden.
Garry Shutler
Dies ist nicht bei allen Klassen möglich. Manchmal möchten Sie nicht alle Abhängigkeiten usw. verspotten und nur eine Dienstprogrammmethode testen.
Jason Cohen
+1, also wahr. Fügen Sie dazu die Anforderung hinzu, manchmal Getter / Setter zu privaten Feldern hinzuzufügen, um den Status für einen Komponententest korrekt einrichten und lesen zu können, obwohl der Status für die Klasse privat sein sollte.
Erikkallen
Schreiben Sie Ihre Tests so, als wäre es ein Dokument mit den Anforderungen an den Lebensunterhalt. Dann würden Sie das Licht sehen. Lesen Sie auch XUnit-Testmuster.
Scott Nimrod
0

Lassen Sie mich hinzufügen, dass Sie, wenn Sie BDD-Prinzipien auf ein TDD-Projekt anwenden, einige der hier aufgeführten Hauptnachteile (Verwirrung, Missverständnisse usw.) beseitigen können. Wenn Sie mit BDD nicht vertraut sind, sollten Sie die Einführung von Dan North lesen. Er entwickelte das Konzept als Antwort auf einige der Probleme, die sich aus der Anwendung von TDD am Arbeitsplatz ergaben. Dans Einführung in BDD finden Sie hier .

Ich mache diesen Vorschlag nur, weil BDD einige dieser Negative anspricht und als Lückenstopp fungiert. Sie sollten dies berücksichtigen, wenn Sie Ihr Feedback sammeln.

Kilhoffer
quelle
Absolut. Sie müssen BDD bei der Bewertung von TDD berücksichtigen.
user9991
Es scheint BDD = verhaltensgetriebene Entwicklung
Hayalci
0

Sie müssen sicherstellen, dass Ihre Tests immer auf dem neuesten Stand sind. Sobald Sie rote Ampeln ignorieren, werden die Tests bedeutungslos.

Sie müssen auch sicherstellen, dass die Tests umfassend sind, oder sobald ein großer Fehler auftritt, wird sich der stickige Verwaltungstyp beschweren, von dem Sie schließlich überzeugt sind, dass Sie Zeit damit verbringen, mehr Code zu schreiben.

qui
quelle
0

Die Person, die meinem Team agile Entwicklung beigebracht hat, glaubte nicht an Planung, Sie haben nur so viel für die kleinste Anforderung geschrieben.

Sein Motto war Refactor, Refactor, Refactor. Ich habe verstanden, dass Refactor bedeutet, nicht vorauszuplanen.

Jack B flink
quelle
-1

Die Entwicklungszeit erhöht sich: Jede Methode muss getestet werden. Wenn Sie eine große Anwendung mit Abhängigkeiten haben, müssen Sie Ihre Daten für Tests vorbereiten und bereinigen.

Mouna Cheikhna
quelle
Ich habe für 36 Jahre entwickelt, jetzt kann dieser Beitrag Ihnen einige gute Ratschläge geben: stackoverflow.com/questions/738539/tdd-how/45971814#45971814
user2288580