it-swarm.com.de

Warum dreht sich bei Agile alles um die testgetriebene Entwicklung (TDD) und nicht um den entwicklungsgetriebenen Test (DDT)?

Ich bin neu in der Agilität, aber nicht testgetriebene Entwicklung . Bei meinen Professoren am College ging es nur um Tests, dann um Code und dann um Tests. Ich bin mir nicht sicher, warum. Aus meiner Sicht sind es viele Vorabkosten, die höchstwahrscheinlich geändert werden, wenn sich Ihr Code weiterentwickelt.

So stelle ich mir TDD vor und warum verwirrt es mich. Wenn ich als TDD-Bauunternehmer ein Haus bauen würde.

  1. Gib mir alle deine Angaben (Geschichten).

  2. Holen Sie sich die Genehmigung für die Spezifikationen.

  3. Teilen Sie alle Spezifikationen in Inspektionen auf, von denen ich denke, dass ich sie benötigen werde (siehe in die Zukunft).

  4. Rufen Sie einen Inspektor an, um sich diese Punkte anzusehen, und sagen Sie mir, dass ich die Inspektion derzeit nicht bestanden habe (danke).

  5. Baue das Haus.

  6. Rufen Sie den Inspektor täglich zurück (nach 2/100).

  7. Oh, schieß, es gab ein Problem mit meinem Verständnis und jetzt muss ich 9 weitere Inspektionen hinzufügen und 27 davon ändern.

  8. Rufen Sie den Inspektor an, der 1/109 passiert.

  9. Verdammt. Warum mag der Inspektor diesen nicht ... oh, ich habe diesen Methodennamen aktualisiert ...

  10. Baue noch mehr.

  11. UGGGGHHHH MEHR ÄNDERUNGEN lassen mich den verdammten Inspektor aktualisieren. Oh, ich versage nein s ** t.

  12. Bin ich schon fertig

Okay, das mag seltsam sein, aber ich sehe einfach nicht, wie ich alle meine Methoden kennen sollte und wie die Dinge funktionieren werden, 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, sind DDT- oder entwicklungsgetriebene Tests, die die Community anscheinend so gut wie vergessen hat.

Nach meinem Verständnis würde DDT für ein Haus so aussehen:

  1. Gib mir alle deine Angaben (Geschichten).

  2. Holen Sie sich die Genehmigung für die Spezifikationen und brechen Sie sie aus.

  3. Starten Sie eine Einheit (das Fundament).

  4. Machen Sie sich Notizen (Kommentare) zu einer kniffligen Logik.

  5. Am Ende vor Beginn der nächsten Einheit die Inspektion durchführen lassen (Test erstellen).

  6. Beheben Sie alle gefundenen Probleme und überprüfen Sie sie erneut.

  7. Genehmigt, dass diese Einheit zur nächsten übergeht.

Wenn wir alle ehrlich sind, klingt das nicht menschlicher und konzentriert sich auf den Entwickler und das Geschäft? Es scheint, als könnten Änderungen schneller vorgenommen werden und ohne den Overhead scheint TDD zu entstehen.

74
nerdlyist

Einer der Vorteile eines TDD-Ansatzes wird nur realisiert, wenn Sie auch aufstrebendes Design verwenden.

In Ihrer ersten Analogie würden Sie also nicht 100 Tests schreiben, da Sie auf keinen Fall wissen, wie Ihre Software aussehen wird.

Sie schreiben einen Test. Sie führen es aus. Es schlägt fehl. Sie schreiben die kleinste Codeeinheit, um Ihren Test zu bestehen. Dann führen Sie Ihren Test erneut aus. Es geht vorbei.

Schreiben Sie nun den nächsten Test und wiederholen Sie den obigen Vorgang.

Dies mag am Anfang wie ein verschwenderischer Ansatz erscheinen, wenn klar ist, was Ihr Code tun soll, aber das Tolle an diesem Ansatz 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, um ihn zu bestehen, 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, also schlägt sie fehl. Als nächstes schreibe ich die einfache, leere Klasse und meine ersten Tests bestehen.

Sobald Sie sich in die Denkweise eingearbeitet haben, ist es sehr schwierig, nicht dabei zu sein und den "altmodischen" Weg zu codieren.

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.

83
Phil Riley

Software ist kein Haus. Intuition ist gut, aber verstehe, dass es nicht immer richtig ist.

Teilen Sie alle Spezifikationen in Inspektionen auf, von denen ich denke, dass ich sie benötigen werde (siehe in die Zukunft).

Das ist nicht richtig. In TDD beschreiben Sie, wie Sie den Code verwenden möchten. Die Spezifikationen sagen: "Es muss ein Haus geben, mit einer Möglichkeit, es zu betreten." Der Test sagt dann "Hey, ich möchte eine Haustür mit einem Knopf haben." Dies ist weit weniger ein Blick in die Zukunft als der Beginn der Implementierung eines Türrahmens, eines Knopfes, einer Tastensperre usw. (so lautet das Argument).

Rufen Sie den Inspektor täglich zurück (nach 2/100).

Das ist nicht richtig. Sie schreiben keine Tests für das Haus. Sie schreiben Tests für den vorderen Türrahmen und machen ihn dann grün. Testen Sie dann, ob die Tür fest ist und grün wird. Sie sollten vielleicht ein Dutzend oder so Tests höchstens zu einem bestimmten Zeitpunkt gebrochen haben. Normalerweise ist es näher an zwei bis vier.

Die Analogie "Rufen Sie den Inspektor an" impliziert auch, dass es einige Zeit dauert, bis die Person herauskommt und ihre Arbeit erledigt. Das Ausführen von Komponententests für eine TDD-Iteration sollte buchstäblich einige Sekunden dauern.

Es scheint, als könnten Änderungen schneller vorgenommen werden und ohne den Overhead scheint TDD zu entstehen.

Der Overhead ist geringer als Sie zu implizieren scheinen. Ein paar Sekunden, um die Tests auszuführen, sind möglicherweise ein halbes Dutzend Mal für die Gesamtentwicklungszeit unerheblich.

Das Problem von dev zuerst ist manchmal, wenn Sie zum Testen kommen, stellen Sie fest, dass es ein großes Problem gibt. Als ob Sie das Bett neben die Toilette stellen und niemand dort leben möchte. Dinge, deren Behebung länger dauert als jede Art von TDD-Overhead. Dinge, die TDD gefangen hätte, da TDD Sie zwingt, Ihren Code von Anfang an zu verwenden und darüber nachzudenken, wie Sie mit ihm kommunizieren können.

Bei meinen Professoren am College ging es nur um Tests, dann um Code und dann um Test.

Alles in allem ist TDD nicht so allgegenwärtig. Viele Orte entwickeln immer noch 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.

86
Telastyn

Die Ähnlichkeiten zwischen dem Erstellen einer physischen Sache und dem Schreiben von Software sind ziemlich gering.

Das heißt, es gibt einen massiven Unterschied, auf den hingewiesen werden sollte:

Es gibt einen Unterschied zwischen "Erstellen eines Tests" und "Ausführen eines Tests".

Im Beispiel des Hausbaus gehen die Anforderungen und Tests dem physischen Ausbau voraus. Und Teile der Testsuite werden kontinuierlich ausgeführt - sogar von mehreren Agenten! Wenn der Bauherr einen 2x4 aufnimmt, "testet" er das Gerät sofort und automatisch gegen seine Vorstellung, "wie ein Sound 2x4 aussieht". Er verfasst keine Anforderungen, nachdem er sie aufgegriffen hat. er überprüft es bereits.

Ebenso bestehen für eine montierte Wand, einen Schaltkasten, die Rohrleitungen usw. - die Prüfungen/Anforderungen bereits; Sie werden implizit und automatisch von den geschulten Augen aller Beschäftigten kontinuierlich ausgeführt . Eine weitere Reihe bereits vorhandener Tests wird beim Besuch des Inspektors ausgeführt. Wenn die Einheiten nicht gebaut wurden, um diesen bereits vorhandenen Test zu bestehen, schlagen sie fehl.

Und ebenso für die gesamte Struktur. Die Pläne existieren bereits für den Ausbau. Bei jedem Schritt des Weges arbeiten die Ingenieure an einer Reihe von Bedingungen, gegen die die Struktur letztendlich getestet wird , wenn der Aufbau abgeschlossen ist .

Allerdings muss nicht jedem physischen Projekt eine große Reihe von Tests vorausgehen. Wenn Sie in Ihre Werkstatt gehen und Holz für eine Spielzeugkiste oder ähnliches zusammenstellen und sich von Ihrer Intuition und Kreativität leiten lassen, ist dies keine strenge TDD-Holzbearbeitung. In diesem Fall verlassen Sie sich im Wesentlichen auf die physikalischen Gesetze des Mediums und Ihre groben Erwartungen, um die Arbeit zu validieren (d. H. "Wenn sie kompiliert wird und funktioniert, ist sie gut!").

Und das ist in Ordnung. Nicht allem müssen strenge Tests vorausgehen.

tl; dr

Auch wenn Konstruktion! = Software schreiben: Konstruktion funktioniert testgetrieben. Die "Bestehens" -Bedingungen für jede Einheit do gehen ihrem Aufbau voraus.

Kombinieren Sie "Ausführen von Tests" nicht mit "Schreiben von Tests".

Nicht alles muss TDD sein.

13
svidgen

Sie sind in die Falle geraten, an die unsinnige Idee zu glauben, dass das Schreiben von Software dem Bau eines Hauses entspricht. Ist es nicht. Es ist analoger zum Erstellen der Architektenzeichnungen und der Berechnungen der Statiker.

Jetzt mit echten Häusern erstellt der Architekt diese Pläne im Voraus. Dann rufen Sie die Bauherren an, die mit dem Bau beginnen, auf Probleme stoßen, Änderungen vornehmen müssen, die Kontrolle über das Gebäude übernehmen, Änderungen wünschen usw. Am Ende kommt der Architekt zurück und berechnet Ihnen mehr, um seine Zeichnungen zu aktualisieren, um sie zu reflektieren Was ist passiert. Dies ist eine beschissene Art, Dinge zu tun, aber der Bau von Häusern dauert lange und ist teuer, daher ist dies der einzig praktikable Weg.

Für das Software-Engineering ist es besser. Das Äquivalent zum Gebäude des Hauses 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 aufzubauen und erst am Ende den Inspektor (QS) aufzurufen, um es zu testen. Wenn Sie diese Überprüfungen automatisieren, kann der Inspektor stattdessen bei jeder Neuerstellung alles erneut überprüfen lassen.

Es spielt keine Rolle, ob Sie einer strengen TDD oder einem eher testorientierten Ansatz folgen, Code zu schreiben, dann einige Tests. Ich bevorzuge den ersten Ansatz, andere den letzteren. Wählen Sie diejenige aus, 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.

11
David Arno

In erster Linie sind die Vorabkosten nicht so hoch, wie Sie denken . Ja, Sie verbringen mehr Zeit mit dem Testen als mit dem Nicht-Testen. Aber wenn Sie eine "Test nach" -Methode durchführen, was verschwenden Sie dann wirklich? Angenommen, TDD dauert 10 Stunden und DDT 6 Stunden. Ihre "zusätzlichen" Vorabkosten betragen nur 4 Stunden. Wenn Sie nun eine Codemetrik oder -anforderung wie 90% Deckung anwenden, werden Ihre TDD- und DDT-Kosten noch enger.

Mit TDD schreiben Sie weniger fehlerhaften Code. Auch wenn Sie die Anforderungen nur als Test formuliert haben, können Sie dies am Ende des Tages tun Beweisen Sie, dass Ihr Code genau das tut, was Sie 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 Produkt zu "verkaufen", das funktioniert, aber anders/besser funktionieren könnte, 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. Eine Testsuite mit guter Abdeckung stellt sicher, dass das Produkt bei der Weiterentwicklung weiterhin ordnungsgemäß funktioniert. Es hilft auch, widersprüchliche Geschäftsregeln hervorzuheben (die über längere Zeiträume auftreten).

Sie wissen nicht, dass es nicht funktioniert. Ohne eine Testsuite wissen Sie nicht, ob Ihr Code so funktioniert, wie Sie denken oder wenn es nur zu funktionieren scheint.

var foo = function(in) {
    if(in == 0) {
      return true
    }
}

Jetzt rufen Sie in Ihrer gesamten Anwendung if(foo()){ doStuff() } auf. Was passiert, wenn ich foo repariere?

var foo = function(in) {
    if(in === 0) {
      return true
    }
}

Sie sollten auch Ihre Tests umgestalten und DRYing . Eine gute Testsuite ist nicht schwer zu warten. Bei gut geschriebenen Atomtests musste ich selten zurückgehen und mehr als 1-2 davon gleichzeitig ändern. Wenn größere Änderungen an der Testsuite vorgenommen wurden, ist es eine riesige rote Fahne, dass etwas nicht stimmt.

Ich sehe nur nicht, wie ich alle meine Methoden kennen sollte und wie die Dinge funktionieren werden, bis mein Code da ist.

Nun, das solltest du nicht. Sie sollten einen Test schreiben, der testet, 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ß, OR Testen ist zu klein.

Zum Beispiel müssen Sie wissen, dass sich eine Tür schließt und verriegelt. Ich würde door.close () und door.lock () testen und diese door.open () gibt false zurück, wenn die Tür verriegelt ist. Das ist es. Wenn Ihre Tests door.lock () sind, setzt ein Flag in der Datenbank. Dann testen Sie zu klein. Der Test muss nicht wissen, wie door.lock () funktioniert, nur dass er funktioniert.

Wenn Sie jetzt einen Test schreiben, der besagt, dass house.isSecure () true zurückgibt, wenn alle Türen und Fenster verriegelt sind. Ohne zuerst auf Türen oder Fenster zu schauen, denken Sie dann zu groß.

Schließlich Möglicherweise sehen Sie eine zu große Arbeitseinheit . Wenn Sie eine Liste mit Anforderungen erhalten, sollten Sie diese so organisieren, dass Sie an der kleinsten Einheit arbeiten. Schreiben Sie den Test nur für dieses Gerät, dann den Code, spülen Sie ihn aus und wiederholen Sie ihn.

Im Wesentlichen ist Ihr Verständnis (die Liste), wie TDD funktionieren sollte, falsch. Sie sollten niemals 2/100 passieren lassen. Sie sollten 1/1 Pass, dann 2/2 Pass, dann 3/3 Pass, dann 4/4 Pass und so weiter haben.

Eine überarbeitete Liste für Sie

  1. Holen Sie sich alle Spezifikationen
  2. Wählen Sie eine Spezifikation
  3. Probier es aus
  4. Code es
  5. Probier es aus
  6. Wenn die Tests bestanden sind, fahren Sie mit 7 fort, andernfalls mit 4
  7. Wenn Sie alle Angaben gemacht haben, gehen Sie zu 8, sonst gehen Sie zu 2
  8. Überprüfen Sie die Spezifikationen mit dem Verbraucher und fügen Sie bei Bedarf neue Spezifikationen hinzu. Bei korrekter Ausführung sollten Sie keine Tests ändern müssen. Fügen Sie einfach neue hinzu. Manchmal kann das Sammeln von Anforderungen auseinanderfallen und Sie müssen Tests hinzufügen, die mit früheren Tests in Konflikt stehen, aber Sie sollten Tests selten ändern müssen.
7
coteyr

Es gibt einige Schlüssel, bei denen ich der Meinung bin, dass die anderen Antworten fehlen.

Drei Vorteile

Erstens sind die Kosten für Fehler und Änderungen zwischen Software und Haus so unglaublich unterschiedlich, dass einige Regeln möglicherweise nicht gelten. Zum Beispiel sind die Kosten für das Testen einer physischen Struktur so hoch, dass Sie ein hohes Maß an Vertrauen in ihre Funktionsweise benötigen, um keine Tests zu verschwenden. Wenn Sie mit Software eine Reihe von Komponententests in 1 bis 5 Sekunden ausführen können, stehen uns 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 kann es albern oder verschwenderisch erscheinen. Aber ich habe genug Unit-Tests gesehen, die so geschrieben wurden, dass sie immer bestehen, selbst wenn der zu testende Code fehlerhaft 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 er fehlschlägt. Wenn Sie den Code schreiben, der zum Bestehen erforderlich ist, und er besteht, wissen Sie, dass Ihr Test einwandfrei ist. Wenn sich der zu testende Code zurückbildet, besteht eine vernünftige Wahrscheinlichkeit, dass Ihr Komponententest ihn abfängt.

Ein dritter Vorteil von TDD, der nicht oft erwähnt wird, besteht darin, dass die resultierende Codegröße und -komplexität oft um eine Größenordnung kleiner ist. Ich war immer stolz darauf, einfachen und prägnanten 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? Da 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 Einstellung 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 früher gearbeitet habe. Schwerwiegende Probleme aufgrund von Code, nach dem niemand gefragt hat, aber einige Entwickler hielten ihn für cool.)

Kostenanalyse

In gewisser Hinsicht haben Sie also Recht. Mit dieser Strategie konnten wir beim Hausbau nicht durchkommen. Es wäre zu teuer. Aber Software ist kein Haus. Software ist billig.

Eine Analogie zu einem Haus ist die Arbeit des Zusammenbaus des Hauses gegenüber einem Software-Compiler.

In einer Nicht-TDD-Welt iterieren Entwickler immer noch. Wir folgen einem Code -> Kompilieren -> Ausführen -> Testzyklus. Wir sind bereits in einem Modell, das erheblich 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 machen. Bei der Programmierung können die meisten Projekte in Sekunden oder Minuten kompiliert werden, sodass es keine Rolle spielt, ob etwas frühzeitig unvollständig ist. Die Kosten für das frühzeitige Durchdenken trivialer Dinge überwiegen in der Regel die Kosten für das Neukompilieren. So kompilieren wir die ganze Zeit neu.

TDD ist das gleiche Prinzip, nur gedreht, damit der Test nach vorne geht. Wenn die Tests supergünstig durchgeführt werden können (damit alles in Sekunden läuft), überwiegen die Kosten für das Durchdenken des Gesamtbilds und 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 stimmen. Das ist der Zweck der Architektur. Identifizieren und planen Sie Vorabbedenken, deren Änderung später teurer wird. Zum Beispiel würden Sie eine Datenbank nicht im laufenden Betrieb auswählen, ohne über Ihre Anforderungen nachzudenken, mit dem Aufbau zu beginnen und einfach zu argumentieren, dass Sie sie später ändern können. Sie müssen es durchdenken.

4
Brandon

Obwohl diese Frage bereits eine akzeptierte Antwort hat, glaube ich, dass ich etwas hinzufügen muss, das von einem nicht geschriebenen Teststil (alle Tests, die manuell von "Testern" nach einem Testverfahren durchgeführt wurden) zu 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 Nicht-TDD.

Im Allgemeinen schreiben Sie einen kleinen 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 durch Hinzufügen von Parametern, Instanzvariablen usw.

Denk darüber nach. Das ist genau so viel Arbeit wie bei TDD. Der einzige Unterschied besteht darin, dass Sie bei TDD die "Test" -Bits separat in eine andere Datei schreiben und sie am Ende nicht löschen. In TDD Sie behalten Ihren Testcode.

Wenn TDD etwas besser organisiert ist, bedeutet dies natürlich, dass etwas mehr Arbeit erforderlich ist, um herauszufinden, wie die Testcodebits von Ihrem tatsächlichen Code getrennt werden können. Wenn Sie jedoch zuvor Komponententests geschrieben haben, erfahren Sie, wie Sie Ihren Code zum Testen modularisieren.

4
slebetman

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 Sinnvolles bewirkt. Sie testen also Ihren Code. Sie können Ad-hoc-Tests durchführen. Das 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.

Jetzt, da Sie über Ihre Teststrategie nachdenken, können Sie zumindest einen Teil davon genauso gut automatisieren ... Und siehe, Sie haben ein gewisses Maß an TDD. Die Tatsache, dass Sie Code schreiben, bis Sie den Test bestehen, ist normal. Das ist es, was Sie sowieso tun, schreiben Sie Code, bis es funktioniert. Es ist gerade jetzt einfach, die Tests zu sprengen.

Aus Gründen, die über den Rahmen hinausgehen, schreiben Sie nicht das Ganze auf einmal. Sie entwerfen die Tests also auch nicht auf einmal. Aber im Grunde ist es das, was es ist. Nur eine bessere Planung des Testens, Sie schreiben den Test nicht immer im Voraus. Manchmal fügen Sie im Laufe der Zeit weitere hinzu und finden Fehler, die Sie nicht erwartet haben, oder machen den Test später robuster. Und manchmal können Sie feststellen, dass Sie keine Tests entwerfen, aber manuelle Tests als mühsam empfinden, 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.

4
joojaa

Warum dreht sich bei Agile alles um die testgetriebene Entwicklung (TDD) und nicht um den entwicklungsgetriebenen Test (DDT)?

Ich zwitschere hier nur rein, weil ich finde, dass die Frage auf eine Tatsache hindeutet ("Agilität dreht sich alles um TDD"), die ich eher zu beanstanden finde. Alle Antworten scheinen diese Tatsache als selbstverständlich zu betrachten. Sie sind gute Antworten, wenn Sie davon ausgehen, dass es bei Agilität hauptsächlich um TDD geht (a.k.a., Testen auf Einheitenebene).

https://en.wikipedia.org/wiki/Agile_software_development#Agile_methods listet ein gutes Dutzend oder mehr verschiedene Entwicklungsmodelle auf.

Ich würde insbesondere verhaltensgesteuerte Entwicklung und funktionsgesteuerte Entwicklung als Denkanstoß anbieten. Ganz andere Bestien, die auch zu allen Vorteilen der grundlegenden TDD führen können, aber weit entfernt von einem einfachen Rot-Grün-Refaktor-Zyklus sind.

Meine Antwort lautet also:

  • "DDT" (a.k.a., Schreiben von Tests nach oder "über" der Implementierung) funktioniert aus realen Gründen nicht. Sobald Sie Zeit- oder Gelddruck bekommen, gehen die Tests aus dem Fenster; und nur Tests zum Nutzen von Tests zu haben, ist sowieso eher meh, IMO.
  • Agile ist nicht alles über testgetriebene Entwicklung (TDD), wenn Sie diesen Begriff so interpretieren, dass er im Grunde genommen "Komponententests für alle Bausteine ​​/ Klassen" bedeutet (welche) ist zumindest laut Wikipedia der Fall). TDD ist nur eine Möglichkeit für eine agile Entwicklung.
  • Es gibt andere Methoden wie BDD oder FDD, die einen Full-Stack-Ansatz verwenden. Sie schreiben Ihre Szenarien immer noch im Voraus, Sie haben immer noch einen Rot-Grün-Refaktor-Zyklus und Sie implementieren immer noch nur, bis Ihre Szenarien grün sind, aber Ihre "Tests" üben per Definition die gesamte Software aus (indem Sie sich wie Benutzerinteraktion verhalten) und niemals nur eine einzige Einheit.

Ich hätte lieber eine Anwendung mit vollständiger BDD/FDD-Abdeckung und ohne Unit-Tests als eine mit vollständiger Unit-Test-Abdeckung und ohne Full-Stack-Tests.

(TDD hat natürlich seinen Platz, zum Beispiel in APIs, aber darüber sprechen wir hier nicht.)

Auch hier versuche ich nicht, alle anderen Antworten zu unterdrücken, sondern nur darauf hinzuweisen, dass die Frage ziemlich eng formuliert ist und das Feld viel mehr zu bieten hat.

2
AnoE

Obwohl Sie es nicht oft so sehen, ist einer der Gründe für Agile, dass das Umschreiben von Code besser ist, als ihn beim ersten Mal gut zu schreiben. Jedes Mal, wenn Sie Code neu schreiben, verbessern Sie den Code und verbessern sich. Wenn Sie es beim ersten Mal "richtig" machen, ist es in der Regel langsamer und spröder.

Die Hausanalogie ist gar nicht so schlecht, aber Sie müssen darüber nachdenken, wie lange wir über den Hausbau Bescheid wissen und wie lange wir über das Software-Engineering Bescheid wissen - auch die Komplexität des Software-Engineerings kommt dem Bau einer langen Brücke näher oder 20-stöckiger Turm als ein Haus. Wir sollten auch berücksichtigen, dass mit dem Bau neuer Sprachen und Werkzeuge jeder Bauherr das Gebäude mit völlig unterschiedlichen Formen, Größen und Materialien bauen wollte. Komplettes Chaos.

Inspektion ist jedoch keine gute Analogie zum Codetest. In der Software sind wir noch nicht einmal so weit, dass wir anständige Inspektoren haben (mit Ausnahme Ihrer Kollegen mit unterschiedlichen Fähigkeiten). Wir haben auch keine Vorschriften, anhand derer wir prüfen können, außer vielleicht einigen meist willkürlichen "Codierungsstandards" (die eher dem Testen der Farbe Ihrer Farbe und Ihres Rasenlayouts als der Struktur ähneln).

Test-first ist eher so, als würden Sie eine Wand bauen, dann üben Sie etwas Druck darauf aus, um die Stabilität zu gewährleisten, bevor Sie sie anheben und auf Ihr Haus legen. Es ist so, als würde man das Fenster messen, um sicherzustellen, dass es in das Loch passt, das Sie hinterlassen haben, bevor Sie versuchen, es zu platzieren.

Wenn Sie eine Reihe von Brücken ohne unsere jahrhundertelangen Vorkenntnisse in Architektur, Muster, Vorschriften und Mathematik 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 wieder aufbauen.

Schließlich ein nicht analoger Punkt: Mit Software verbessern Sie jedes Mal, wenn Sie einen Abschnitt Ihres Codes neu schreiben dürfen, sowohl Ihren Code als auch Ihre Fähigkeiten erheblich. Nutzen Sie jede Gelegenheit, um Code neu zu schreiben. TDD kann eine gute Ausrede sein.

0
Bill K