Ich bin neu in der agilen, aber nicht testgetriebenen Entwicklung . Bei meinen Professoren am College drehte sich alles um die Idee von Tests, dann Code, dann Tests. Ich bin mir nicht sicher, warum ich das verstehe. Aus meiner Sicht sind es viele Vorlaufkosten, die sich höchstwahrscheinlich ändern werden, wenn sich Ihr Code weiterentwickelt.
So stelle ich mir TDD vor und warum es mich verwirrt. Wenn ich als TDD-Bauunternehmer ein Haus bauen würde.
Geben Sie mir alle Ihre Angaben (Geschichten).
Lassen Sie sich von den Spezifikationen genehmigen.
Teilen Sie alle Spezifikationen in Inspektionen auf, von denen ich glaube, dass sie erforderlich sind (siehe in die Zukunft).
Rufen Sie einen Inspektor an, um sich diese Punkte anzuschauen, und teilen Sie mir mit, dass ich die Inspektion nicht bestanden habe (Danke).
Baue das Haus.
Rufen Sie den Inspektor täglich zurück (vorbei an 2/100).
Oh, schieß, es gab ein Problem mit meinem Verständnis und jetzt muss ich 9 weitere Inspektionen hinzufügen und 27 davon ändern.
Rufen Sie den Inspektor an, der 1/109 passiert.
Verdammt. Warum gefällt der Inspektor nicht ... oh, ich habe diesen Methodennamen aktualisiert ...
Baue noch mehr.
UGGGGHHHH MEHR ÄNDERUNGEN lassen Sie mich den verdammten Inspektor aktualisieren. Oh, ich versage nicht.
Bin ich schon fertig
Okay, das ist vielleicht komisch, aber ich sehe einfach nicht, wie ich alle meine Methoden kennen sollte und wie die Dinge funktionieren, bis mein Code da ist. In 99% der Fälle muss ich zurückgehen und einen Komponententest auf irgendeine Weise aktualisieren und im Laufe der Zeit weitere hinzufügen. Es scheint nur rückwärts.
Was angemessener erscheint, ist DDT oder entwicklungsgetriebenes Testen, was die Community anscheinend so gut wie vergessen hat.
Nach meinem Verständnis würde DDT für ein Haus so aussehen:
Geben Sie mir alle Ihre Angaben (Geschichten).
Holen Sie sich die Genehmigung für die Spezifikationen und brechen Sie sie aus.
Starten Sie eine Einheit (das Fundament).
Machen Sie sich Notizen (Kommentare) zu einer kniffligen Logik.
Am Ende vor Beginn der nächsten Einheit die Inspektion durchführen (Test erstellen).
Beheben Sie alle gefundenen Probleme und überprüfen Sie sie erneut.
Genehmigt, dass dieses Gerät zum nächsten wechselt.
Wenn wir alle ehrlich sind, klingt das nicht menschlicher und konzentriert sich auf Entwickler und Unternehmen? Es scheint, dass Änderungen schneller vorgenommen werden können und ohne dass der Overhead TDD zu erstellen scheint.
quelle
Antworten:
Einer der Vorteile eines TDD-Ansatzes wird nur realisiert, wenn Sie auch Emergent Design ausführen.
In Ihrer ersten Analogie würden Sie also nicht 100 Tests schreiben, da Sie unmöglich wissen werden, wie Ihre Software aussehen wird.
Sie schreiben einen Test. Du machst es. Es schlägt fehl. Sie schreiben die kleinste Codeeinheit, um den Test zu bestehen. Dann führen Sie Ihren Test erneut durch. Es geht vorbei.
Schreiben Sie nun den nächsten Test und wiederholen Sie den obigen Vorgang.
Dies mag zu Beginn wie eine verschwenderische Herangehensweise erscheinen, wenn es offensichtlich ist, was Ihr Code bewirken soll, aber das Tolle an dieser Herangehensweise ist, dass Ihre Testabdeckung immer hoch ist und das Code-Design auf diese Weise sauberer ist.
Als Methode geht es Hand in Hand mit der Paarprogrammierung; Ein Paar schreibt den Test, das nächste schreibt den Code, damit er erfolgreich ist, und schreibt dann den nächsten Test und so weiter.
Ich benutze diesen Ansatz sogar, wenn ich eine neue Klasse schreibe. Der erste Test ist ein Aufruf zum Initiieren des Klassenkonstruktors. Aber ich habe die Klasse noch nicht geschrieben, deshalb schlägt sie fehl. Als nächstes schreibe ich die einfache, leere Klasse, und mein erster Test besteht.
Wenn Sie erst einmal in die Denkweise eingedrungen sind, ist es sehr schwierig, sich nicht darauf einzulassen und die "altmodische" Art und Weise zu kodieren.
Ich würde empfehlen, in einer guten agilen Umgebung zu arbeiten, um dies zu lernen, oder ein paar gute agile Bücher zu lesen (Clean Code und Clean Coder sind beide sehr gut), um dies besser zu verstehen.
quelle
Software ist kein Haus. Die Intuition ist gut, aber verstehen Sie, dass es nicht immer richtig ist.
Das ist nicht richtig. In TDD beschreiben Sie, wie Sie den Code verwenden möchten. In den technischen Daten heißt es: "Es muss ein Haus geben, das man betreten kann." Der Test sagt dann: "Hey, ich möchte eine Vordertür mit einem Knauf haben." Dies ist weitaus weniger ein Blick in die Zukunft als der Einstieg in den Bau eines Türrahmens, eines Knopfs, eines Schlosses usw. (so lautet das Argument).
Das stimmt nicht. Sie schreiben keine Tests für das Haus. Sie schreiben Tests für den Vordertürrahmen und machen sie dann grün. Dann wird geprüft, ob die Tür fest und grün ist. Sie sollten vielleicht ein Dutzend oder so Tests zu einem bestimmten Zeitpunkt höchstens gebrochen haben. Normalerweise ist es eher zwei vor vier.
Außerdem impliziert die Analogie "Rufe den Inspektor aus", dass die Person einige Zeit braucht, um herauszukommen und ihre Arbeit zu erledigen. Das Ausführen von Unit-Tests für eine TDD-Iteration sollte buchstäblich einige Sekunden dauern.
Der Aufwand ist geringer als Sie vermuten. Ein paar Sekunden, um die Tests vielleicht ein halbes Dutzend Mal auszuführen, sind für die gesamte Entwicklungszeit unerheblich.
Das Problem von dev besteht manchmal darin, dass Sie beim Testen feststellen, dass es ein großes Problem gibt. Als würde man das Bett neben die Toilette stellen und niemand möchte dort ein Problem haben. Dinge, deren Behebung länger dauert als jeglicher TDD-Aufwand. Dinge, die TDD abgefangen hätte, da TDD Sie von Anfang an dazu zwingt, Ihren Code zu verwenden und darüber nachzudenken, wie Sie mit ihm interagieren können.
Alles in allem ist TDD nicht allgegenwärtig. Viele Orte entwickeln noch immer zuerst und viele der angeblichen Vorteile von TDD sind übertrieben. Wichtig ist, dass Sie die Tests machen und sie gut machen. Die Reihenfolge, in der Sie die Arbeit erledigen, ist weniger wichtig.
quelle
open_door
sollte ich keine Flagge für übergeben müssentoilet_flushed
. Deshalb schreibe ich meinen Test nicht so und deshalb hat mein Code diese "Ecken und Kanten" nicht. Code, der völlig ohne ausreichende Berücksichtigung der Art und Weise geschrieben wurde, in der er aufgerufen wird, weist häufig seltsame Schnittstellen oder Annahmen / Voraussetzungen auf.Die Ähnlichkeiten zwischen dem Erstellen einer physischen Sache und dem Schreiben von Software sind ziemlich gering.
Trotzdem gibt es einen großen Unterschied, auf den wir hinweisen sollten:
Es gibt einen Unterschied zwischen "Verfassen eines Tests" und "Ausführen eines Tests".
Im Beispiel ein Haus zu bauen, die Anforderungen und Prüfungen haben Sie vor dem physischen buildout. Und Teile der Testsuite werden ununterbrochen ausgeführt - sogar von mehreren Agenten! Wenn der Erbauer einen 2x4 aufnimmt, "testet" er die Einheit sofort und automatisch anhand seiner Vorstellung, "wie ein 2x4-Sound aussieht". Er verfasst keine Anforderungen, nachdem er sie aufgegriffen hat. Er führt bereits bestehende Überprüfungen durch.
Ebenso für eine montierte Wand, einen Elektrokasten, die Rohrleitungen usw. - die Prüfungen / Anforderungen sind bereits vorhanden; Sie werden implizit und automatisch von den geschulten Augen aller am Arbeitsplatz tätigen Personen ausgeführt . Eine weitere Reihe bereits vorhandener Tests wird ausgeführt, wenn der Inspektor sie besucht. Wenn die Einheiten nicht so gebaut wurden, dass sie diesen bereits vorhandenen Test bestehen, schlagen sie fehl.
Und ebenso für die Struktur als Ganzes. Die Pläne bestehen bereits vor dem Buildout. Bei jedem Schritt auf dem Weg arbeiten die Ingenieure an einer Reihe von Bedingungen, unter denen die Struktur nach Abschluss des Ausbaus letztendlich getestet wird.
Allerdings muss nicht jedem physischen Projekt eine riesige Reihe von Tests vorausgehen. Wenn Sie in Ihre Werkstatt gehen und anfangen, Holz für eine Spielzeugkiste oder etwas anderes zusammenzustellen, und sich von Ihrer Intuition und Kreativität leiten lassen, ist das keine rigorose TDD-Holzbearbeitung. In diesem Fall verlassen Sie sich grundsätzlich auf die physikalischen Gesetze des Mediums und Ihre groben Erwartungen, um die Arbeit zu validieren (dh "Wenn es kompiliert und funktioniert, ist es gut!").
Und das ist in Ordnung. Nicht allen muss ein strenger Test vorausgehen.
tl; dr
Auch wenn Bauen! = Software schreiben: Bauen funktioniert testgetrieben. Die „passing“ Bedingungen für jede Einheit tun ihre buildout vorangestellt werden .
Kombinieren Sie "Tests ausführen" nicht mit "Tests schreiben".
Nicht alles muss TDD sein.
quelle
Sie sind in die Falle gegangen, wenn Sie glauben, dass das Schreiben von Software dem Bauen eines Hauses entspricht. Ist es nicht. Es ist analog zur Erstellung der Architektenzeichnungen und der Berechnungen der Tragwerksplaner.
Jetzt mit echten Häusern erstellt der Architekt diese Pläne im Voraus. Dann rufen Sie die Bauherren an, die mit dem Bauen beginnen, auf Probleme stoßen, Dinge ändern, die Gebäudesteuerung übernehmen, Änderungen wünschen usw. Am Ende kommt der Architekt zurück und fordert Sie auf, seine Zeichnungen entsprechend zu aktualisieren Was ist passiert. Dies ist eine beschissene Vorgehensweise, aber der Bau von Häusern dauert lange und ist teuer. Es ist daher die einzig praktikable Vorgehensweise.
Für das Software-Engineering sieht es besser aus. Das Äquivalent zu dem Gebäude, in dem sich das Haus befindet, besteht darin, dass der Compiler Ihren Code in eine kompilierte Einheit (Bibliothek, App, Web-App usw.) umwandelt. Es ist sehr schnell und billig, dies hunderte Male am Tag zu tun. Daher ist es nicht sinnvoll, das Haus beim Hinzufügen von Funktionen wiederholt neu zu erstellen und den Inspektor (QS) erst am Ende zum Testen aufzurufen. Wenn Sie diese Überprüfungen automatisieren, kann der Inspektor stattdessen bei jeder Neuerstellung alles erneut überprüfen.
Es spielt keine Rolle, ob Sie eine strenge TDD oder einen eher testorientierten Ansatz für das Schreiben von Code als für einige Tests verfolgen . Ich bevorzuge den ersten Ansatz, andere den letzteren. Wählen Sie diejenige, die zu Ihnen passt. Wichtig ist, dass Sie diese Schecks im Laufe der Zeit erstellen. Sie helfen später, wenn Sie den Code ändern möchten, indem sie Sie vor Funktionsunterbrechungen an anderer Stelle warnen, wenn Sie etwas ändern.
quelle
In erster Linie sind die Vorlaufkosten nicht so hoch, wie Sie denken . Ja, Sie verbringen mehr Zeit mit dem Testen, als wenn Sie keine Tests durchführen. Aber wenn Sie eine "Test nach" -Methode durchführen, was verschwenden Sie dann wirklich? Nehmen wir an, TDD dauert 10 Stunden und DDT dauert 6 Stunden. Ihre "zusätzlichen" Vorabkosten betragen nur 4 Stunden. Wenn Sie jetzt eine Codemetrik oder eine Anforderung wie 90% Deckung anwenden, werden Ihre TDD- und DDT-Kosten noch enger.
Mit TDD schreiben Sie weniger fehlerhaften Code. Auch wenn dies nur daran liegt, dass Sie die Anforderungen als Test formuliert haben, können Sie am Ende des Tages nachweisen, dass Ihr Code genau das tut, was Sie von ihm wollten. Vielleicht wollten Sie, dass es das Falsche tut, aber das ist kein Fehler, der eine Änderungsanforderung ist. Das ist wichtig. Es ist einfacher, ein funktionierendes Produkt zu "verkaufen", könnte aber anders / besser funktionieren, als ein Produkt zu verkaufen, das als nicht funktionierend wahrgenommen wird. Mit TDD ist es buchstäblich unmöglich, den Test zu bestehen und nicht funktionierenden Code zu schreiben. Möglicherweise haben Sie die Anforderungen nicht verstanden und den falschen, aber funktionierenden Code geschrieben.
TDD ist besser, je älter die Codebasis wird. Versuchen Sie, das Refactoring ohne oder mit einer schlecht implementierten Testsuite durchzuführen. Schon eine einfache Änderung kann zu Fehlern führen. Mit einer Test-Suite mit guter Abdeckung wird sichergestellt, dass das Produkt bei seiner Weiterentwicklung weiterhin wie gewünscht funktioniert. Es hilft auch, widersprüchliche Geschäftsregeln hervorzuheben (die über längere Zeiträume hinweg auftreten).
Sie wissen nicht, dass es nicht funktioniert. Ohne eine Testsuite wissen Sie nicht, ob Ihr Code so funktioniert, wie Sie es glauben, oder ob er nur zu funktionieren scheint.
Jetzt rufen Sie in Ihrer gesamten Anwendung an.
if(foo()){ doStuff() }
Was passiert, wenn ich foo behebe?Sie sollten auch Ihre Tests überarbeiten und trocknen . Eine gute Testsuite ist nicht schwer zu warten. Mit gut geschriebenen Atomtests musste ich selten mehr als 1-2 von ihnen gleichzeitig ändern. Bei größeren Änderungen an der Testsuite ist es eine riesige rote Fahne, dass etwas nicht stimmt.
Das solltest du nicht. Sie sollten einen Test schreiben, der prüft, ob eine Arbeitseinheit erledigt ist. Wenn Sie das Gefühl haben, Dinge zu testen, von denen Sie möglicherweise nichts wissen, denken Sie zu groß, ODER Tests sind zu klein.
Zum Beispiel müssen Sie wissen, dass eine Tür sich schließt und sich verriegelt. Ich würde door.close () und door.lock () testen und door.open () gibt false zurück, wenn die Tür verschlossen ist. Das ist es. Wenn Ihre Tests door.lock () sind, setzt es ein Flag in der Datenbank. Dann testen Sie zu klein. Der Test muss nicht wissen, wie door.lock () funktioniert, nur dass es funktioniert.
Wenn Sie jetzt einen Test schreiben, der besagt, dass house.isSecure () true zurückgibt, wenn alle Türen und Fenster gesperrt sind. Ohne zuerst auf Türen oder Fenster zu schauen, denkt man zu groß.
Schließlich sehen Sie möglicherweise eine zu große Arbeitseinheit . Wenn Sie Ihre Anforderungsliste erhalten, sollten Sie diese so organisieren, dass Sie an der kleinsten Einheit arbeiten. Schreiben Sie den Test nur für diese Einheit, dann den Code, dann spülen und wiederholen.
Im Wesentlichen ist Ihr Verständnis (die Liste), wie TDD funktionieren sollte, ausgeschaltet. Sie sollten niemals 2/100 verpassen. Sie sollten 1/1 Passing, dann 2/2 Passing, dann 3/3 Passing, dann 4/4 Passing und so weiter haben.
Eine überarbeitete Liste für Sie
quelle
Es gibt einige Schlüssel, von denen ich denke, dass die anderen Antworten fehlen.
Drei Vorteile
Erstens sind die Fehler- und Änderungskosten zwischen Software und einem Haus so unterschiedlich, dass einige Regeln möglicherweise nicht zutreffen. Zum Beispiel sind die Kosten für das Testen einer physischen Struktur so hoch, dass Sie ein hohes Maß an Vertrauen in deren Funktion benötigen, um das Testen nicht zu verschwenden. Wenn Sie mit Software eine Reihe von Komponententests in 1 bis 5 Sekunden ausführen können, stehen Ihnen verschiedene Optionen zur Verfügung.
Zweitens besteht der Zweck der Ausführung eines Tests, von dem Sie erwarten, dass er fehlschlägt, bevor Sie den zu testenden Code schreiben, darin, den Test selbst zu überprüfen. Sicher, es kann albern oder verschwenderisch wirken. Aber ich habe genug Unit-Tests gesehen, die so geschrieben wurden, dass sie immer Bestand haben, auch wenn der zu testende Code kaputt ist. Dies kann leicht passieren, wenn Sie den zu testenden Code schreiben, manuell testen und dann den Komponententest schreiben. Wenn Sie einen Komponententest schreiben, sehen Sie, dass dieser fehlschlägt. Wenn Sie dann den Code schreiben, der zum Bestehen des Tests erforderlich ist, und der Test besteht, wissen Sie, dass der Test einwandfrei ist. Wenn der zu testende Code zurückgeht, besteht eine vernünftige Chance, dass Ihr Komponententest ihn abfängt.
Ein dritter Vorteil von TDD, der nicht oft erwähnt wird, ist, dass die resultierende Codegröße und -komplexität oft eine Größenordnung kleiner ist. Ich war immer stolz darauf, einfachen und präzisen Code zu bevorzugen. Bis ich anfing TDD zu üben. TDD hat mir gezeigt, dass das, was ich vorher getan hätte, übermäßiger Code wäre. Warum passiert das? Weil Sie einen Test schreiben, schreiben Sie dann Code, um den Test zu bestehen. Wenn der Test bestanden ist, sind Sie damit fertig. Wenn Sie in dieser Denkweise sind, ist es schwierig, versehentlich "zusätzlichen" Code zu schreiben.
(Zusätzlicher Code war ein Problem, das ich bei einem Produkt beobachtet habe, an dem ich gearbeitet habe. Schwerwiegende Probleme aufgrund von Code, nach dem niemand gefragt hat, aber einige Entwickler dachten, er wäre cool.)
Kostenanalyse
In gewisser Hinsicht haben Sie also Recht. Wir konnten mit dieser Strategie beim Hausbau nicht durchkommen. Es wäre zu teuer. Aber Software ist kein Haus. Software ist billig.
Eine Analogie mit einem Haus ist die Arbeit des Zusammenbaus des Hauses gegenüber einem Software-Compiler.
In einer Welt ohne TDD iterieren Entwickler immer noch. Wir folgen einem Code -> Kompilieren -> Ausführen -> Testzyklus. Wir befinden uns bereits in einem Modell, das wesentlich vom Hausbau abweicht. Wenn Ihre Bauarbeiter einen Türrahmen bauen, dann eine Tür bauen und dann den Rahmen neu bauen müssen, weil die Tür zu groß dafür ist, haben Sie ein Kostenproblem. So verbringen Sie mehr Zeit im Voraus, um sicherzustellen, dass Sie alles perfekt erhalten. Bei der Programmierung können die meisten Projekte in Sekunden oder Minuten kompiliert werden, sodass es keine Rolle spielt, ob etwas von Anfang an fehlerhaft ist. Die Kosten für das Vorausdenken über Kleinigkeiten überwiegen normalerweise die Kosten für das Neukompilieren. So kompilieren wir die ganze Zeit neu.
TDD ist das gleiche Prinzip, nur gedreht, damit der Test im Vordergrund steht. Wenn das Testen supergünstig ist (alles läuft in Sekunden), überwiegen die Kosten für das Durchdenken des Gesamtbilds, der perfekten Gesamtlösung in einer einzigen Big-Bang-Codierungsiteration, die Kosten für das Refactoring.
Außer...
Es gibt einige Dinge in der Programmierung, bei denen diese Argumente nicht zutreffen. Das ist der Zweck der Architektur. Identifizieren und planen Sie im Voraus Bedenken, deren spätere Änderung teurer sein wird. Sie würden zum Beispiel keine Datenbank im Handumdrehen auswählen, ohne über Ihre Bedürfnisse nachzudenken, mit dem Aufbau zu beginnen und einfach zu argumentieren, dass Sie sie später ändern können. Sie müssen es durchdenken.
quelle
Ich habe mich oft darüber gewundert, bis ich ein paar Projekte von TDD gemacht habe. Es gibt eine sehr prägnante und umfassende Erklärung, die mir dabei aufgefallen ist:
Wenn Sie Code schreiben, müssen Sie sicherstellen, dass der Code etwas Bedeutendes bewirkt. So testen Sie Ihren Code. Sie können Ad-hoc-Tests durchführen. Testen funktioniert jedoch besser, wenn Sie überlegen, wie Sie testen sollen, bevor Sie anfangen, Dinge zu tun. Sie entwerfen also die Teststrategie, bevor Sie mit dem Testen beginnen.
Nun, da Sie über Ihre Teststrategie nachdenken, können Sie zumindest einen Teil davon auch automatisieren ... Und siehe, Sie haben eine gewisse TDD-Ebene. Die Tatsache, dass Sie Code schreiben, bis Sie den Test bestehen, ist normal. Das ist, was Sie sowieso tun, schreiben Sie Code, bis es funktioniert. Es ist jetzt einfach, die Tests zu sprengen.
Aus Gründen, die den Rahmen sprengen, schreiben Sie nicht alles auf einmal. Sie entwerfen die Tests also auch nicht auf einmal. Aber im Grunde ist es das, was es ist. Nur eine bessere Planung der Tests, Sie schreiben Test nicht immer im Voraus. Manchmal fügt man im Laufe der Zeit mehr hinzu und findet Fehler, die man nicht erwartet hat, oder macht den Test später robuster. Und manchmal müssen Sie möglicherweise keine Tests entwerfen, sondern es ist mühsam, manuell zu testen, damit Sie die Tests später durchführen können.
TDD ist also nur eine extreme Methode, um zu sehen, wie Sie Ihre Arbeit validieren.
quelle
Obwohl diese Frage meiner Meinung nach bereits eine akzeptierte Antwort hat, muss ich etwas hinzufügen, das von einem Designstil ohne schriftliche Prüfung (alle von "Testern" nach einem Testverfahren manuell durchgeführten Tests) an TDD stammt. Dies sind nur meine persönlichen Beobachtungen, obwohl ich glaube, dass sie ziemlich universell sind.
Wenn Sie etwas Neues schreiben, etwas, das Sie noch nie zuvor getan haben, gibt es keinen signifikanten Unterschied zwischen TDD und TDD.
Im Allgemeinen schreiben Sie ein kleines Stück Code, um eine Idee zu untersuchen, fügen dann einige fest codierte Bits zum "Testen" hinzu und kompilieren und / oder führen sie dann aus. Wenn es funktioniert, löschen Sie das fest codierte Material und verallgemeinern den Code, indem Sie Parameter, Instanzvariablen usw. hinzufügen.
Denk darüber nach. Das ist genau so viel Arbeit wie bei TDD. Der einzige Unterschied besteht darin, dass Sie in TDD die "Test" -Bits separat in eine andere Datei schreiben und sie am Ende nicht löschen. In TDD behalten Sie Ihren Testcode .
Wenn TDD etwas besser organisiert ist, bedeutet dies natürlich, dass ein wenig mehr Arbeit erforderlich ist, um herauszufinden, wie Sie die Test-Codebits von Ihrem tatsächlichen Code trennen können. Wenn Sie jedoch Unit-Tests geschrieben haben, lernen Sie, wie Sie Ihren Code zum Testen modularisieren.
quelle
Ich zwitschere nur hier rein, weil ich finde, dass die Frage eine Tatsache nahelegt ("agil dreht sich alles um TDD"), die ich eher ablehnend finde. Alle Antworten scheinen diese Tatsache als selbstverständlich anzusehen. Sie sind gute Antworten, wenn Sie davon ausgehen, dass es bei Agile in erster Linie um TDD geht (auch bekannt als Testen auf Geräteebene).
https://en.wikipedia.org/wiki/Agile_software_development#Agile_methods listet ein gutes Dutzend oder mehr verschiedene Entwicklungsmodelle auf.
Als Denkanstoß biete ich besonders Verhaltensorientierte Entwicklung und Funktionsorientierte Entwicklung an. Völlig andere Bestien, die auch zu allen Vorteilen der grundlegenden TDD führen können, aber weit von einem einfachen Rot-Grün-Refaktor-Zyklus entfernt sind.
Meine Antwort lautet also:
Ich hätte lieber eine Anwendung mit vollständiger BDD / FDD-Abdeckung und keinen Unit-Tests als eine mit vollständiger Unit-Test-Abdeckung und keinen Full-Stack-Tests.
(TDD hat natürlich seinen Platz, zum Beispiel in APIs, aber darüber reden wir hier nicht.)
Auch hier versuche ich nicht, alle anderen Antworten herabzusprechen. Ich möchte nur darauf hinweisen, dass die Frage ziemlich eng formuliert ist und das Feld viel mehr zu bieten hat.
quelle
Obwohl Sie es nicht oft so geschrieben sehen, ist der Grund für Agile, dass das Neuschreiben von Code besser ist als das Schreiben beim ersten Mal. Jedes Mal, wenn Sie Code neu schreiben, verbessern Sie den Code und verbessern sich. Das erste Mal "richtig" zu machen, ist in der Regel langsamer und spröder.
Die Haus-Analogie ist gar nicht so schlecht, aber man muss sich überlegen, wie lange wir über Hausbau Bescheid wissen und wie lange wir über Software-Engineering Bescheid wissen - auch die Komplexität des Software-Engineerings kommt dem Aufbau einer langen Brücke näher oder 20-stöckiger Turm als ein Haus. Wir sollten auch bedenken, dass mit dem Bau neuer Sprachen und Werkzeuge jeder Bauherr das Gebäude mit völlig anderen Formen, Größen und Materialien bauen wollte. Komplettes Chaos.
Das Prüfen ist jedoch keine gute Analogie zum Testen von Code. In der Software sind wir noch nicht einmal so weit, dass wir anständige Inspektoren haben (ausgenommen Ihre Kollegen mit unterschiedlichen Qualifikationen). Wir haben auch keine Vorschriften, an denen wir uns orientieren müssen, außer vielleicht einigen meist willkürlichen "Kodierungsstandards" (die eher dem Testen der Farbe Ihres Lacks und Ihres Rasenlayouts als der Struktur gleichen).
Test-first ist eher so, als würden Sie eine Mauer bauen, als wenn Sie etwas Druck darauf ausüben, um die Stabilität zu gewährleisten, bevor Sie sie anheben und auf Ihr Haus stellen. Es ist so, als würde man das Fenster vermessen, um sicherzustellen, dass es in das Loch passt, das Sie verlassen haben, bevor Sie versuchen, es zu platzieren.
Wenn Sie eine Reihe von Brücken ohne unsere jahrhundertelangen Architekturkenntnisse, Muster, Vorschriften und Berechnungen bauen müssten, die wir derzeit nachweisen müssen, dass unsere Brücken funktionieren, bevor wir sie bauen, würden Sie Ihre Brücken wahrscheinlich viel testen und neu bauen.
Endlich ein Punkt, bei dem es sich nicht um eine Analogie handelt: Mit Software können Sie jedes Mal, wenn Sie einen Teil Ihres Codes neu schreiben, sowohl Ihren Code als auch Ihre Fähigkeiten erheblich verbessern. Nutzen Sie jede Chance, um Code neu zu schreiben. TDD kann eine gute Entschuldigung sein.
quelle