Es gibt einige, aber die Vorteile überwiegen bei weitem die Nachteile.
Es gibt eine steile Lernkurve.
Viele Entwickler scheinen zu erwarten, dass sie mit der Erstprogrammierung vom ersten Tag an effizient arbeiten können. Leider braucht es viel Zeit, um im gleichen Tempo wie bisher Erfahrungen zu sammeln und zu programmieren. Sie können es nicht umgehen.
Genauer gesagt ist es sehr leicht, sich zu irren. Sie können sehr leicht (mit sehr guten Absichten) eine ganze Reihe von Tests schreiben, die entweder schwierig zu pflegen sind oder die das falsche Zeug testen. Es ist schwierig, hier Beispiele zu nennen. Solche Probleme lassen sich nur mit Erfahrung lösen. Sie müssen ein gutes Gespür für das Trennen von Bedenken und das Entwerfen für die Testbarkeit haben. Mein bester Rat wäre, mit jemandem zu programmieren, der TDD wirklich gut kennt.
Du machst vorne mehr Codierung.
Test-first bedeutet, dass Sie keine Tests überspringen können (was gut ist) und dass Sie am Ende mehr Code schreiben werden. Das bedeutet mehr Zeit. Auch hier kann man nicht umgehen. Sie werden mit Code belohnt, der einfacher zu warten, zu erweitern und im Allgemeinen weniger Fehler enthält, der jedoch einige Zeit in Anspruch nimmt.
Kann für Manager ein schwerer Verkauf sein.
Software-Manager beschäftigen sich in der Regel nur mit Zeitplänen. Wenn Sie zu Test-First-Programmierung wechseln und plötzlich 2 Wochen brauchen, um eine Funktion anstelle einer zu vervollständigen, wird es ihnen nicht gefallen. Dies ist definitiv ein Kampf, den es wert ist, gekämpft zu werden, und viele Manager sind aufgeklärt genug, um ihn zu bekommen, aber es kann ein harter Verkauf sein.
Kann ein schwerer Verkauf an andere Entwickler sein.
Da es eine steile Lernkurve gibt, mögen nicht alle Entwickler die Erstprogrammierung. Tatsächlich würde ich vermuten, dass es den meisten Entwicklern zunächst nicht gefällt. Du kannst Dinge wie Pair-Programming machen, um sie auf den neuesten Stand zu bringen, aber es kann schwierig werden.
Am Ende überwiegen die Vorteile die Nachteile, aber es hilft nichts, wenn Sie die Nachteile einfach ignorieren. Wenn Sie von Anfang an wissen, womit Sie es zu tun haben, können Sie einige, wenn nicht alle Nachteile aushandeln.
Test-first setzt voraus, dass Sie folgenden Code schreiben:
Wenn Ihr Projekt diese Anforderungen nicht erfüllt, werden Sie Schwierigkeiten haben. Die Veranstalter von TDD haben keine guten Antworten darauf, was darauf hindeutet, dass Sie Ihr Produkt neu designen, um besser in diese Linien zu fallen. Es gibt Situationen, in denen dies unmöglich oder unerwünscht ist.
In der Praxis kann es auch ein großes Problem für mich sein, wenn Leute denken, dass die Test-First-Tests tatsächlich irgendetwas über die korrekte Funktion des Programms beweisen. In vielen Fällen ist dies nicht der Fall, aber selbst in den Fällen, in denen dies der Fall ist, ist dies alles andere als ein vollständiges Bild der Richtigkeit. Die Leute sehen Hunderte von bestandenen Tests und gehen davon aus, dass es sicher ist, weniger zu testen, da sie vor TDD sowieso nur ein paar Hundert Testfälle durchgeführt haben. Nach meiner Erfahrung bedeutet TDD, dass Sie noch mehr Integrationstests benötigen, da die Entwickler auch die falsche Sicherheit und den Schmerz haben, alle Tests zu ändern, um einen großen Redaktor zu erstellen. Dies kann Entwickler zu interessanten Workarounds führen.
Beispiele:
Mein persönliches bestes Beispiel ist das Schreiben von Sicherheitscode für asp.net. Wenn sie in einer feindlichen Umgebung in der Maschinenkonfiguration ausgeführt werden sollen, werden sie gestrichen, signiert und versiegelt, und da sie auf IIS-Gott-Objekten ausgeführt werden, ist es sehr schwierig, sehr viel richtig zu verspotten. Fügen Sie einige Einschränkungen für die Leistung und die Speichernutzung hinzu, und Sie verlieren sehr schnell die Flexibilität, Platzhalterobjekte in den verbleibenden Bereichen zu verwenden.
Jede Art von Mikrocontroller oder anderer ressourcenarmer Umgebungscode ist möglicherweise nicht für ein echtes Design im OO-Stil geeignet, da die Abstraktionen nicht optimiert werden und Sie über niedrige Ressourcenbeschränkungen verfügen. Dasselbe gilt in vielen Fällen auch für Hochleistungsroutinen.
quelle
Der größte Nachteil, den ich gesehen habe, ist nicht bei TDD selbst, sondern bei Praktizierenden. Sie verfolgen einen dogmatischen und eifrigen Ansatz, bei dem alles auf die Probe gestellt werden muss . Manchmal (oft) ist das nicht nötig. Dies ist möglicherweise auch nicht praktikabel (z. B. Einführung einer Organisation in TDD).
Ein guter Ingenieur findet Kompromisse und wendet die richtige Balance zwischen dem Zeitpunkt, dem Ort und dem Verfahren an, bei dem der Test zuerst angewendet wird. Wenn Sie ständig mehr Zeit mit der Entwicklung von Tests verbringen als mit dem eigentlichen Code (um den Faktor 2-3 oder mehr), sind Sie in Schwierigkeiten.
Mit anderen Worten, sei pragmatisch und vernünftig mit TDD (oder irgendetwas in der Softwareentwicklung für diese Angelegenheit.)
quelle
Ich habe Anfang August 2009 mit TDD begonnen und mein gesamtes Unternehmen überzeugt, im September / Oktober 2009 zu TDD zu wechseln. Derzeit ist das gesamte Entwicklerteam vollständig konvertiert, und das Festschreiben von nicht getestetem Code für das Repo wird als eine schlechte Sache angesehen und als problematisch eingestuft. Es hat für uns großartig funktioniert und ich kann mir nicht vorstellen, wieder auf Cowboy-Codierung umzusteigen.
Es gibt jedoch zwei Probleme, die ziemlich auffällig sind.
Die Testsuite muss gewartet werden
Wenn Sie TDD ernst meinen, werden Sie am Ende viele Tests schreiben . Darüber hinaus braucht es einige Zeit und Erfahrung, um die richtige Granularität der Tests zu erkennen (Übertreiben ist fast so schlimm wie Untertreiben). Diese Tests sind ebenfalls Code und für Bitrot anfällig. Dies bedeutet, dass Sie sie wie alles andere pflegen müssen: Aktualisieren Sie sie, wenn Sie Bibliotheken aktualisieren, von denen sie abhängen, und ändern Sie von Zeit zu Zeit die Einstellungen sogar schlicht falsch. Wenn Sie Glück haben, können Sie sie einfach löschen. Oft werden Sie jedoch die nützlichen Teile extrahieren und an die neue Architektur anpassen.
Das Testen von Abstraktionen läuft von Zeit zu Zeit aus
Wir verwenden Django, das ein ziemlich gutes Test-Framework hat. Manchmal werden jedoch Annahmen getroffen, die leicht im Widerspruch zur Realität stehen. Beispielsweise kann eine Middleware die Tests unterbrechen. Einige Tests gehen von einem Caching-Backend aus. Wenn Sie eine "echte" Datenbank (nicht SQLite3) verwenden, wird die Vorbereitung der Datenbank für die Tests viel Zeit in Anspruch nehmen. Sicher, Sie können (und sollten) SQLite3 und eine In-Memory-Datenbank für Tests verwenden, die Sie lokal durchführen. Einige Codes verhalten sich jedoch je nach verwendeter Datenbank anders. Die Einrichtung eines Continuous Integration Servers, der in einer realistischen Konfiguration ausgeführt wird, ist ein Muss.
(Einige Leute werden Ihnen sagen, dass Sie alle Dinge wie die Datenbank verspotten sollten, oder Ihre Tests sind nicht "rein", aber das ist nur eine ideologische Aussage. Wenn Sie Fehler in Ihrem Verspottungscode machen (und glauben Sie mir, das werden Sie), Ihre Testsuite wird wertlos sein.)
Die beschriebenen Probleme machen sich jedoch erst bemerkbar, wenn Sie mit TDD weit fortgeschritten sind ... Wenn Sie gerade erst mit TDD beginnen (oder an kleineren Projekten arbeiten), ist das Umgestalten von Tests kein Problem.
quelle
Für mich gibt es ein tiefes psychologisches Problem mit Tests, wenn ich versuche, sie ausgiebig anzuwenden, wie bei TDD: Wenn sie vorhanden sind, codiere ich schlampig, weil ich darauf vertraue, dass die Tests Probleme aufdecken werden. Aber wenn es keine Tests gibt, um ein Sicherheitsnetz bereitzustellen, codiere ich sorgfältig, und das Ergebnis ist ausnahmslos besser als bei Tests.
Vielleicht bin es nur ich. Aber ich habe auch irgendwo gelesen, dass Autos mit allen möglichen Sicherheitsmechanismen häufiger abstürzen (weil die Fahrer wissen, dass die Sicherheitsmerkmale vorhanden sind). TDD kann mit einigen Personen nicht kompatibel sein.
quelle
Eine Situation, in der mir Test-First wirklich im Weg steht, ist, wenn ich schnell eine Idee ausprobieren und prüfen möchte, ob es funktionieren kann, bevor ich eine ordnungsgemäße Implementierung schreibe.
Mein Ansatz ist normalerweise:
Manchmal komme ich nicht zu Schritt 2.
In diesem Fall hat TDD für mich mehr Nachteile als Vorteile:
Wenn ich also einige neue Ideen erforschen muss, verwende ich kein TDD und führe Unit-Tests nur dann ein, wenn ich das Gefühl habe, dass der neue Code irgendwo ankommt.
quelle
Nachteile oder Kosten von TDD
Hinweis: Es gibt verschiedene Arten von TDDs. Unabhängig von Einheit, BDD, ATDD oder anderen Varianten bleiben viele der Schwierigkeiten bestehen
Nebenwirkungen
Unabhängig davon, ob es sich um Verspottungen, Fixtures oder Funktionstests handelt, sind Abhängigkeiten von externen Zuständen oder Systemen häufig die Ursache für die größte Komplexität bei Tests, Unklarheiten bei der Testdurchführung und das größte Risiko, Fehler zu machen. Einige Probleme, die ich gesehen habe:
Sie müssen Ihre Herangehensweise an das Codieren ändern, für einige wird es eine drastische Änderung sein.
Unterschiedliche Menschen codieren auf ganz unterschiedliche Weise. In TDD müssen Sie mit einem Test beginnen, der ein bestimmtes Verhalten bestätigt, und dann implementieren, damit der Test erfolgreich ist. Ich habe gesehen und war ein Programmierer, dessen Programmierung TDD nicht förderlich war. Es dauerte ungefähr zwei Monate, bis ich mich daran gewöhnt hatte, meinen Entwicklungsansatz zu ändern.
Es braucht Zeit, um zu verstehen, was Sie am Testen interessiert und was Sie nicht am Testen interessiert.
Jedes Team sollte eine explizite Entscheidung treffen, an welcher Stelle beim Testen die Grenze gezogen werden soll. Welche Dinge schätzen sie, die sie testen möchten, und welche nicht. Es ist oft ein schmerzhafter Prozess, zu lernen, wie man gute Tests schreibt und worauf es Ihnen beim Testen ankommt. In der Zwischenzeit wird der Code so lange im Fluss bleiben, bis Konsistenz sowohl im Stil als auch in der Herangehensweise besteht.
Unit Test spezifisch: große Refaktoren
Ein großer oder grundlegender Umbau einer signifikanten Codebasis mit Zehntausenden von Komponententests verursacht enorme Kosten, um alle Tests zu aktualisieren. Dies äußert sich oft in einer Zurückweisung gegen das Ausführen eines Refaktors, auch wenn dies nur aufgrund der damit verbundenen Kosten richtig ist.
quelle
Meine Analogie sind Barrieren auf einer Scalextric-Spur. Wenn Sie sie anziehen, werden Sie weit weniger vorsichtig.
Die Leute bekommen auch ein bisschen Platz für ihre Tests - weil sie gut laufen, glauben sie, dass der Code vollständig getestet ist, während es nur der Anfang des Testprozesses ist.
Für mich ist TDD ein Sprungbrett für BDD. Eine Reihe von Tests, die ausgeführt werden, hilft Entwicklern nicht wirklich, ohne zu wissen, was die Tests bewirken. Bei BDD erfolgt die Testausgabe in Englisch, wodurch die Tests dokumentiert und das Verständnis des Systems verbessert werden.
quelle
Der Vorteil von TDD besteht darin, dass Sie gezwungen sind, Ihren Code vor Leuten zu schützen, die ihn nicht verstehen. Ja, dazu gehören oft Sie. Aber was passiert, wenn der Code es nicht wert ist, geschützt zu werden? Es gibt eine Menge Code, der gar nicht erst vorhanden sein sollte! Das Problem mit TDD ist also, wenn es um Entwickler geht, die schlechten Code schreiben. TDD wird ihnen wahrscheinlich nicht dabei helfen, guten Code zu schreiben. Es ist viel wahrscheinlicher, dass sie auch schreckliche Tests schreiben. Somit wird TDD in ihrem Fall nur zu dem Durcheinander beitragen; Schlecht geschriebene und / oder redundante Tests machen nicht mehr Spaß als andere Arten von schlechtem Code.
quelle