it-swarm-eu.dev

Was sind die Nachteile der Test-First-Programmierung?

Es ist heutzutage der letzte Schrei. "Jeder" empfiehlt es. Das an und für sich macht mich misstrauisch.

Welche Nachteile haben Sie bei der Test-First-Entwicklung (testgetrieben) festgestellt? Ich suche nach persönlichen Erfahrungen von sachkundigen Praktizierenden - ich kann die hypothetischen Überlegungen von hundert Möchtegern anderswo im Internet lesen.

Ich frage nicht, weil ich TDD hassen möchte, sondern weil es meine Aufgabe ist, den Softwareentwicklungsprozess zu verbessern. Je mehr wir über die Probleme erfahren können, auf die Menschen stoßen, desto größer sind die Chancen, den Prozess zu verbessern.

48
Alex Feinman

Es gibt einige, aber die Vorteile bei weitem überwiegen die Nachteile.

Es gibt eine steile Lernkurve.

Viele Entwickler scheinen zu erwarten, dass sie vom ersten Tag an effizient mit Test-First-Programmierung arbeiten können. Leider braucht es viel Zeit, um Erfahrungen zu sammeln und mit der gleichen Geschwindigkeit wie zuvor 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 schwer zu warten sind oder die falschen Dinge testen. Es ist schwierig, hier Beispiele zu nennen - diese Art von Problemen erfordert einfach Erfahrung, um sie zu lösen. Sie müssen ein gutes Gefühl dafür haben, Bedenken zu trennen und auf Testbarkeit zu achten. Mein bester Rat hier wäre, Paarprogrammierung mit jemandem zu machen, der TDD wirklich gut kennt.

Sie programmieren mehr im Voraus.

Test-first bedeutet, dass Sie keine Tests überspringen können (was gut ist) und dass Sie am Ende mehr Code schreiben müssen. Das bedeutet mehr Zeit. Auch hier kommt man nicht darum herum. Sie werden mit Code belohnt, der einfacher zu warten, zu erweitern und im Allgemeinen weniger Fehler enthält, aber Zeit braucht.

Kann für Manager ein schwieriger Verkauf sein.

Software-Manager befassen sich im Allgemeinen nur mit Zeitplänen. Wenn Sie zur 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, der 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 für andere Entwickler ein harter Verkauf sein.

Da es eine steile Lernkurve gibt, mögen nicht alle Entwickler Test-First-Programmierung. Tatsächlich würde ich vermuten, dass die meisten Entwickler es zuerst nicht mögen. Sie können Dinge wie Paarprogrammierung tun, um sie auf den neuesten Stand zu bringen, aber es kann ein schwieriger Verkauf sein.

Am Ende überwiegen die Vorteile die Nachteile, aber es hilft nicht, 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.

41
Jaco Pretorius

Test-first setzt voraus, dass Sie folgenden Code schreiben:

  • im Unit-Test testbar
  • das, was Sie entwickeln, hat einen offensichtlichen Ansatz und erfordert kein umfangreiches Prototyping oder Experimentieren
  • dass Sie nicht zu stark umgestalten müssen oder dass Sie die Zeit haben, Hunderte oder Tausende von Testfällen wiederholt neu zu schreiben
  • nichts ist versiegelt
  • alles ist modular
  • alles ist injizierbar oder verspottbar
  • dass Ihre Organisation Wert auf niedrige Fehler legt, um die Ressourcensenke zu rechtfertigen
  • dass es von Vorteil ist, auf Unit-Test-Ebene zu testen

Wenn Ihr Projekt diese Anforderungen nicht erfüllt, haben Sie Schwierigkeiten. Die Promotoren von TDD haben keine guten Antworten auf diese Frage, die darauf hindeuten, dass Sie Ihr Produkt neu gestalten, 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 geben, wenn Leute denken, dass die Test-First-Tests tatsächlich etwas ü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 es weit von einem vollständigen Bild der Korrektheit entfernt. Die Leute sehen Hunderte von bestandenen Tests und gehen davon aus, dass es sicher ist, weniger zu testen, da sie vor TDD ohnehin 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 haben und der Schmerz, alle Tests zu ändern, um einen großen Redakteur auszuführen, dazu führen kann, dass Entwickler interessante Workarounds durchführen.

Beispiele:

Mein persönliches bestes Beispiel ist das Schreiben eines Sicherheitscodes für asp.net. Wenn sie in einer feindlichen Umgebung über die Computerkonfiguration ausgeführt werden sollen, werden sie überprüft, signiert und versiegelt, und da sie gegen IIS Gottobjekte) ausgeführt werden, sind sie sehr schwer zu verspotten Wenn Sie einige Einschränkungen für die Leistung und die Speichernutzung hinzufügen, verlieren Sie sehr schnell die Flexibilität, Platzhalterobjekte in den verbleibenden Bereichen zu verwenden.

Jede Art von Mikrocontroller oder anderem Code für ressourcenarme Umgebungen ist möglicherweise nicht wirklich möglich OO), da die Abstraktionen nicht optimiert werden und Sie niedrige Ressourcenlimits haben. Dasselbe gilt für In vielen Fällen auch Hochleistungsroutinen.

36
Bill

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 getestet werden muss . Manchmal (das ist oft so) ist das nicht notwendig. Dies ist möglicherweise auch nicht praktikabel (z. B. Einführung einer Organisation in TDD).

Ein guter Ingenieur findet Kompromisse und wendet das richtige Gleichgewicht zwischen wann/wo/wie Test zuerst anzuwenden. Wenn Sie ständig mehr Zeit damit verbringen, Tests anstelle von tatsächlichem Code zu entwickeln (um den Faktor 2-3 oder mehr), sind Sie in Schwierigkeiten.

Mit anderen Worten, seien Sie pragmatisch und vernünftig mit TDD (oder irgendetwas in der Softwareentwicklung).

26
luis.espinal

Ich habe Anfang August 2009 angefangen, TDD zu machen, und mein gesamtes Unternehmen davon ü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 schlechte Sache angesehen und in Frage gestellt. Es hat bei 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 gepflegt werden

Wenn Sie es mit TDD ernst meinen, werden Sie am Ende viele Tests schreiben. Darüber hinaus dauert es einige Zeit und Erfahrung, um die richtige Granularität von Tests zu erkennen (Übertreiben ist fast so schlimm wie Übertreiben). Diese Tests sind auch 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 überarbeiten Sie sie von Zeit zu Zeit. Wenn Sie große Änderungen an Ihrem Code vornehmen, sind viele Tests plötzlich veraltet oder sogar einfach falsch. Wenn Sie Glück haben, können Sie sie einfach löschen, aber oft werden Sie die nützlichen Teile extrahieren und sie an die neue Architektur anpassen.

Testen von Abstraktionen von Zeit zu Zeit

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. Bei einigen Tests werden Annahmen über ein Caching-Backend getroffen. Wenn Sie eine "echte" Datenbank (nicht SQLite3) verwenden, nimmt die Vorbereitung der Datenbank für die Tests viel Zeit in Anspruch. Natürlich können (und sollten) Sie SQLite3 und eine In-Memory-Datenbank für Tests verwenden, die Sie lokal durchführen, aber einige Codes verhalten sich je nach verwendeter Datenbank nur unterschiedlich. Das Einrichten eines Continuous Integration Servers, der in einem realistischen Setup 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 spricht nur für die Ideologie. Wenn Sie Fehler in Ihrem Verspottungscode machen (und glauben Sie mir, werden Sie), Ihre Testsuite wird wertlos sein.)

Dies alles sagte, die Probleme, die ich beschrieben habe, machen sich erst bemerkbar, wenn Sie mit TDD ziemlich weit fortgeschritten sind ... Wenn Sie gerade erst mit TDD beginnen (oder an kleineren Projekten arbeiten), wird das Test-Refactoring kein Problem sein.

6
Ryszard Szopa

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 erkennen. Aber wenn es keine Tests gibt, um ein Sicherheitsnetz bereitzustellen, codiere ich sorgfältig und das Ergebnis ist immer besser als bei Tests.

Vielleicht bin ich es nur. Aber ich habe auch irgendwo gelesen, dass Autos mit allen Arten von Sicherheitsvorkehrungen eher zum Absturz kommen (weil die Fahrer wissen, dass die Sicherheitsmerkmale vorhanden sind). Vielleicht ist dies etwas, das man anerkennen muss. TDD kann mit einigen Personen nicht kompatibel sein.

4
Joonas Pulakka

Eine Situation, in der Test-First mir wirklich im Weg steht, ist, wenn ich schnell eine Idee ausprobieren und prüfen möchte, ob sie funktionieren kann, bevor ich eine ordnungsgemäße Implementierung schreibe.

Mein Ansatz ist normalerweise:

  1. Implementieren Sie etwas, das läuft (Proof of Concept).
  2. Wenn es funktioniert, konsolidieren Sie es, indem Sie Tests hinzufügen, das Design verbessern und das Refactoring durchführen.

Manchmal komme ich nicht zu Schritt 2.

In diesem Fall hat sich herausgestellt, dass die Verwendung von TDD für mich mehr Nachteile als Vorteile hat:

  • Das Schreiben von Tests während der Implementierung des Proof-of-Concept verlangsamt mich nur und unterbricht meinen Gedankenfluss: Ich möchte eine Idee verstehen und keine Zeit damit verschwenden, Details meiner ersten groben Implementierung zu testen.
  • Es kann länger dauern, um herauszufinden, ob meine Idee etwas wert ist oder nicht.
  • Wenn sich herausstellt, dass die Idee nutzlos war, muss ich sowohl meinen Code als auch meine gut geschriebenen Unit-Tests wegwerfen.

Wenn ich also einige neue Ideen erforschen muss, verwende ich kein TDD und führe Unit-Tests nur ein, wenn ich das Gefühl habe, dass der neue Code irgendwohin kommt.

2
Giorgio

Nachteile oder Kosten von TDD

Hinweis: Es gibt verschiedene Arten von TDD. Unabhängig von Einheit, BDD, ATDD oder anderen Varianten bleiben viele der Schwierigkeiten bestehen

Nebenwirkungen

Unabhängig davon, ob es sich um Verspottungen, Vorrichtungen 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, Verwirrung beim Testen und das größte Risiko, Fehler zu machen. Einige Probleme, die ich gesehen habe:

  • Verspotten: Vergessen Sie, die Reihenfolge der Anrufe zu bestätigen
  • Verspotten: Mock passt nicht zu einem echten Anruf oder einer echten Antwort
  • Fixture: Der Test basiert auf unrealistischen Daten und maskiert andere Probleme
  • Vorrichtung: Testen Sie einen unmöglichen Zustand in der Produktion
  • Funktionell: Falsche Build-Unterbrechungen, da das abhängige System vorübergehend nicht verfügbar ist
  • Funktionell: Die Testgeschwindigkeit ist sehr langsam

Sie müssen Ihre Herangehensweise an die Codierung ändern, für einige wird es eine drastische Änderung sein.

Unterschiedliche Personen 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 einen Programmierer gesehen und war ein Programmierer, dessen Programmierung TDD nicht förderlich war. Es dauerte ungefähr 2 Monate, bis ich mich an die Änderung meines Entwicklungsansatzes gewöhnt hatte.

Es braucht Zeit, um zu verstehen, was Sie am Testen interessiert und was Sie am Testen nicht interessiert.

Jedes Team sollte explizit entscheiden, wo es beim Testen die Grenze ziehen möchte. Welche Dinge schätzen sie, die sie testen wollen, und welche nicht. Es ist oft ein schmerzhafter Prozess, zu lernen, wie man gute Tests schreibt und was Sie am Testen wirklich interessiert. In der Zwischenzeit wird sich der Code weiter im Fluss befinden, bis sowohl Stil als auch Ansatz konsistent sind.

nit Test spezifisch: große Refaktoren

Ein großer oder grundlegender Refaktor einer signifikanten Codebasis mit Zehntausenden von Komponententests verursacht enorme Kosten, um alle Tests zu aktualisieren. Dies äußert sich häufig in einem Pushback gegen die Durchführung eines Refactors, selbst wenn dies nur aufgrund der damit verbundenen Kosten richtig ist.

1
dietbuddha

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 dies nur der Anfang des Testprozesses ist.

Für mich ist TDD ein Sprungbrett für BDD. Eine Reihe von Tests, die ausgeführt werden, helfen Entwicklern nicht wirklich, ohne zu wissen, was die Tests bewirken. Bei BDD erfolgt die Testausgabe in englischer Sprache, wodurch die Tests dokumentiert werden und das Verständnis des Systems verbessert wird.

0
Robbie Dee