TDD vs. Unit Testing [geschlossen]

117

Meine Firma ist ziemlich neu darin, unseren Code zu testen. Ich habe einige Zeit über TDD und Unit-Tests gelesen und bin von deren Wert überzeugt. Ich habe versucht, unser Team davon zu überzeugen, dass TDD die Mühe wert ist, zu lernen und unsere Einstellung zu unserer Programmierung zu ändern, aber es ist ein Kampf. Was mich zu meinen Fragen bringt.

Es gibt viele in der TDD-Community, die sehr religiös sind, wenn es darum geht, den Test und dann den Code zu schreiben (und ich bin dabei), aber bringt ein Kompromiss für ein Team, das mit TDD zu kämpfen hat, immer noch zusätzliche Vorteile?

Es kann mir wahrscheinlich gelingen, das Team dazu zu bringen, Unit-Tests zu schreiben, sobald der Code geschrieben ist (möglicherweise als Voraussetzung für das Einchecken von Code), und ich gehe davon aus, dass das Schreiben dieser Unit-Tests immer noch wertvoll ist.

Was ist der beste Weg, um ein kämpfendes Team in TDD zu bringen? Und wenn dies nicht gelingt, lohnt es sich immer noch, Komponententests zu schreiben, selbst wenn der Code geschrieben wurde?

BEARBEITEN

Was ich davon abgehalten habe, ist, dass es wichtig ist, dass wir irgendwo im Codierungsprozess mit dem Testen von Einheiten beginnen. Für diejenigen im Team, die das Konzept aufgreifen, sollten Sie sich mehr auf TDD konzentrieren und zuerst testen. Vielen Dank für alle Beiträge.

NACHVERFOLGEN

Wir haben kürzlich ein neues kleines Projekt gestartet und ein kleiner Teil des Teams verwendete TDD, der Rest schrieb Unit-Tests nach dem Code. Nachdem wir den Codierungsteil des Projekts abgeschlossen hatten, waren diese Schreibeinheitentests nach dem Code überrascht, dass die TDD-Codierer bereits ausgeführt wurden und einen solideren Code aufwiesen. Es war ein guter Weg, um die Skeptiker zu gewinnen. Wir haben noch viele wachsende Schmerzen vor uns, aber der Kampf der Willen scheint vorbei zu sein. Vielen Dank für alle, die Ratschläge gegeben haben!

Walter
quelle
1
Sie können diesen Thread hilfreich finden: stackoverflow.com/questions/917334/should-i-use-tdd
Randolpho
29
+1 für das FOLLOW UP. Das ist eine großartige Geschichte.
Carl Manaster

Antworten:

76

Wenn das Team bei der Implementierung von TDD ins Wanken gerät, aber zuvor noch keine Komponententests erstellt hat, erstellen Sie zunächst Unit-Tests, nachdem der Code geschrieben wurde. Selbst nach dem Code geschriebene Unit-Tests sind besser als gar keine Unit-Tests!

Sobald sie sich mit Unit-Tests (und allem, was damit verbunden ist) auskennen, können Sie daran arbeiten, dass sie zuerst die Tests erstellen ... und dann den Code.

Justin Niessner
quelle
3
Das ist richtig, das Team hat vorher keine Unit-Tests erstellt. Dies fühlt sich wie ein schönes Sprungbrett für eine vollständige TDD an.
Walter
Kann dem nicht mehr zustimmen. Tatsächlich glaube ich, dass ich vor einigen Monaten etwas Ähnliches für eine ähnliche Frage geschrieben habe. Wo ist es ... Aah! stackoverflow.com/questions/917334/should-i-use-tdd/…
Randolpho
27

Es lohnt sich absolut noch, die Unit-Tests nach dem Schreiben des Codes zu schreiben. Es ist nur so, dass es manchmal oft schwieriger ist, weil Ihr Code nicht testbar war und Sie ihn möglicherweise überkompliziert haben.

Ich denke, ein guter pragmatischer Weg, um ein Team in TDD zu bringen, besteht darin, die alternative Methode des "Test während der Entwicklung" in der Übergangsphase oder möglicherweise langfristig bereitzustellen. Sie sollten zu TDD-Codeabschnitten ermutigt werden, die ihnen natürlich erscheinen. In Codeabschnitten, bei denen es schwierig zu sein scheint, sich zuerst dem Test zu nähern, oder wenn Objekte verwendet werden, die durch einen nicht agilen A & D-Prozess vorgegeben sind, können Entwickler die Option erhalten, einen kleinen Abschnitt des Codes zu schreiben und anschließend Tests zu schreiben, um dies abzudecken Code und Wiederholen dieses Vorgangs. Das Schreiben von Komponententests für einen Code unmittelbar nach dem Schreiben dieses Codes ist besser, als überhaupt keine Komponententests zu schreiben.

Kaleb Brasee
quelle
16

Meiner bescheidenen Meinung nach ist es besser, eine 50% ige Testabdeckung mit "Code first, test after" und einer 100% abgeschlossenen Bibliothek zu haben, als eine 100% ige Testabdeckung und eine 50% abgeschlossene Bibliothek mit TDD. Nach einer Weile werden Ihre Entwicklerkollegen es hoffentlich unterhaltsam und lehrreich finden, Tests für den gesamten publicCode zu schreiben, den sie schreiben, damit TDD sich in ihre Entwicklungsroutine einschleicht.

Asbjørn Ulsberg
quelle
3
Ich verstehe Ihre Abweichung, bin aber besorgt über die "100% abgeschlossene Bibliothek" mit 50% Testabdeckung ... nur aus meiner Erfahrung heraus, dass jeder Code, der von einigen Tests nicht abgedeckt wird, mindestens einen Fehler enthält. Oder
anders
2
Ein anderer Weg, es auszudrücken, ist Buggy-Code, der veröffentlicht wurde, ist besser als perfekter Code, der für immer schmachtet. Offensichtlich gibt es Ausnahmen Husten NASA Husten , aber zum größten Teil bekommen Sie Ihren Code da draußen. Sie können nach der Veröffentlichung noch Tests hinzufügen.
JCDyer
3
Was meinst du mit "100% abgeschlossene Bibliothek"? Betrachten Sie es als vollständig, wenn es fehlerhaft ist? Nehmen Sie nicht getestet in die Definition von erledigt auf?
Pascal Thivent
10
getestet zu werden ist keine ausreichende Bedingung, um fehlerfrei zu sein
fa.
2
Die Testabdeckung, gemessen mit Testabdeckungswerkzeugen, ist ein zweischneidiges Schwert. Wenn dies durch Aufrufen aller Methoden auf der IUT erreicht wird, die Tests jedoch nicht wirklich das Verhalten testen, das wahrscheinlich beschädigt wird, haben Entwickler und andere Interessengruppen ein falsches Sicherheitsgefühl. Die gesamte Bewegung in Richtung TDD in Ihrem Unternehmen kann in Ihrem Gesicht explodieren, wenn kritisches Verhalten nicht getestet wird, Sie jedoch eine 100% ige Testabdeckung haben. Das Wichtigste ist nicht Quantität, sondern Qualität.
Doug Knesek
12

Ich habe das gerade in einem Kalender gelesen: "Jede Regel, die bis zum Äußersten ausgeführt wird, wird lächerlich oder sogar gefährlich." Mein Vorschlag ist also, nicht religiös zu sein. Jedes Mitglied Ihres Teams muss ein Gleichgewicht zwischen dem finden, was es beim Testen als "richtig" empfindet. Auf diese Weise wird jedes Mitglied Ihres Teams am produktivsten sein (anstatt beispielsweise zu überlegen, warum ich diesen Test schreiben muss?).

Einige Tests sind also besser als keine, Tests nach dem Code sind besser als wenige Tests und Tests vor dem Code sind besser als nach. Aber jeder Schritt hat seine eigenen Vorzüge und Sie sollten nicht einmal kleine Schritte missbilligen.

Aaron Digulla
quelle
"Was sie fühlen" Als Entwickler erinnere ich mich nicht daran, jemals den (richtigen) Wunsch gehabt zu haben, automatisierte Unit-Tests durch meine eigenen Gefühle durchzuführen, nur durch manuelle. Ich glaube nicht, dass ich alleine bin und keine Aufregung beim Testen habe
Gennady Vanin Геннадий Ванин
@ vgv8: Das heißt, deine Tests helfen dir nicht. Es kann viele Gründe dafür geben; Ich schlage vor, tiefer zu graben. Jedes Projekt profitiert von guten Tests und leidet unter schlechten. Sie werden feststellen, wenn Sie anfangen, gute Tests zu schreiben, und ab diesem Zeitpunkt kann Sie nichts mehr davon abhalten, mehr zu schreiben.
Aaron Digulla
Was sich für mich richtig anfühlt, ist eine Teststufe, die abdeckt, was die Programmiereinheiten tun sollten, und von einer funktionalen Ebene aus: Was Benutzer normalerweise tun, einschließlich der schlechten Ergebnisse, die manche als "gemeldete Fehler" bezeichnen. Wenn ein Fehler bestätigt wird, wird mindestens ein Test geschrieben! Je größer das Projekt und je größer das Team, desto wichtiger ist dies.
DaFi4
12

Bei TDD geht es um Design! Wenn Sie es also verwenden, werden Sie sicher sein, dass Ihr Code testbar ist, was das Schreiben Ihrer Tests erleichtert. Wenn Sie Tests schreiben, nachdem der Code geschrieben wurde, sind sie immer noch wertvoll, aber meiner Meinung nach verschwenden Sie Zeit, da Sie wahrscheinlich kein testbares Design haben.

Ein Vorschlag, den ich Ihnen machen kann, um Ihr Team davon zu überzeugen, TDD einzuführen, ist die Verwendung einiger der Techniken, die in Fearless Change: Muster für die Einführung neuer Ideen von Mary Lynn Manns und Linda Rising beschrieben sind .

Diego Dias
quelle
3
+1: Testgesteuerte Entwicklung bedeutet, dass das Design von Testüberlegungen bestimmt wurde.
S.Lott
+1. Die späteren Komponententests helfen Ihnen natürlich, aber Sie würden die Vorteile eines "testbaren Designs" verlieren, wenn Sie keine Komponententests im Voraus schreiben.
Noufal Ibrahim
9

Wenn sie neu im Testen sind, als IMO, beginnen Sie mit dem Testen von Code, der bereits geschrieben wurde, und beginnen Sie langsam damit, zuerst Tests zu schreiben. Als jemand, der versucht, TDD zu lernen und neu in Unit-Tests zu sein, fiel es mir schwer, eine vollständige 180 zu machen und meine Einstellung zu ändern, um Tests vor dem Code zu schreiben. Der Ansatz, den ich verfolge, ist also eine Art 50-50-Mischung ;; Wenn ich genau weiß, wie der Code aussehen wird, schreibe ich den Code und schreibe dann einen Test, um ihn zu überprüfen. In Situationen, in denen ich mir nicht ganz sicher bin, beginne ich mit einem Test und arbeite mich rückwärts vor.

Denken Sie auch daran, dass das Schreiben von Tests zur Überprüfung von Code nichts Falsches ist, anstatt Code zur Erfüllung von Tests zu schreiben. Wenn Ihr Team den TDD-Weg nicht gehen möchte, erzwingen Sie ihn nicht.

Wayne Molina
quelle
6

Es kann mir wahrscheinlich gelingen, das Team dazu zu bringen, Unit-Tests zu schreiben, sobald der Code geschrieben ist (möglicherweise als Voraussetzung für das Einchecken von Code), und ich gehe davon aus, dass das Schreiben dieser Unit-Tests immer noch wertvoll ist.

Es besteht absolut kein Zweifel daran, dass in Unit-Tested-Code ein Wert enthalten ist (unabhängig davon, wann Tests geschrieben wurden), und ich füge "Der Code ist Unit-Tested" in die "Definition of Done" ein. Menschen können TDD verwenden oder nicht, solange sie testen.

In Bezug auf die Versionskontrolle verwende ich gerne " Entwicklungszweige " mit einer Unit-Tested- Richtlinie (dh der Code wird kompiliert und erstellt, alle Unit-Tests bestehen). Wenn Features fertig sind, werden sie von den Entwicklungszweigen im Trunk veröffentlicht. Mit anderen Worten, der Trunk-Zweig ist der " Done-Zweig " (kein Müll auf dem Trunk!) Und hat eine Versandrichtlinie (kann jederzeit veröffentlicht werden), die strenger ist und mehr Dinge enthält als "Unit Tested".

Pascal Thivent
quelle
4

Dies ist etwas, mit dem Ihr Team seine eigenen Erfolge haben muss, bevor es anfängt, daran zu glauben. Ich werde über meine nUnit-Offenbarung für jeden schimpfen, der sich interessiert:

Vor ungefähr 5 Jahren habe ich nUnit bei der Arbeit an einem Projekt entdeckt. Wir hatten V1.0 fast fertiggestellt und ich habe ein paar Tests erstellt, um dieses neue Tool auszuprobieren. Wir hatten viele Fehler (offensichtlich!), Weil wir ein neues Team waren, mit einer engen Frist, hohen Erwartungen (klingt vertraut?) Usw. Wie auch immer, wir haben 1.0 in und haben mit 1.1 angefangen. Wir haben das Team ein wenig umgestaltet und mir wurden 2 Entwickler zugewiesen. Ich habe eine einstündige Demo für sie gemacht und ihnen gesagt, dass alles, was wir geschrieben haben, einen Testfall haben muss. Wir sind während des 1.1-Entwicklungszyklus ständig hinter dem Rest des Teams hergelaufen, weil wir mehr Code geschrieben haben, die Unit-Tests. Wir haben am Ende mehr gearbeitet, aber hier ist die Auszahlung - als wir endlich mit dem Testen begannen, hatten wir genau 0 Fehler in unserem Code. Wir haben allen anderen beim Debuggen und Reparieren ihrer Fehler geholfen. Im Postmortem, als die Anzahl der Fehler auftauchte,

Ich bin nicht dumm genug zu glauben, dass Sie Ihren Weg zum Erfolg testen können, aber ich bin fest davon überzeugt, wenn es um Unit-Tests geht. Das Projekt übernahm nUnit und verbreitete sich aufgrund eines Erfolgs bald für alle .Net-Projekte auf das Unternehmen. Der Gesamtzeitraum für unser V1.1-Release betrug 9 Entwicklungswochen, es war also definitiv KEIN Erfolg über Nacht. Langfristig erwies es sich jedoch als erfolgreich für unser Projekt und das Unternehmen, für das wir Lösungen entwickelt haben.

Keine Rückerstattung Keine Rückgabe
quelle
"Das Projekt hat nUnit übernommen und sich bald für alle .Net-Projekte auf das Unternehmen ausgeweitet." Und was tun, wenn ein Produkt / Projekt C # -, Java-, C ++ - und SQL Server-Code enthält?
Gennady Vanin Геннадий Ванин
Ich weiß nicht ... Finden Sie eine Möglichkeit, alle Komponenten zu testen, bevor Sie sie für die Produktion bereitstellen? Unit-Tests sind nur eine Facette eines umfassenden Testplans, bevor er live geht. Sie können in jedem Szenario Löcher stechen.
Keine Rückerstattung Keine Rückgabe
4

Es besteht kein Zweifel, dass das Testen (zuerst, während oder sogar danach) Ihren Speck spart und Ihre Produktivität und Ihr Vertrauen verbessert. Ich empfehle es zu übernehmen!

Ich war in einer ähnlichen Situation, weil ich ein "Noob" -Entwickler war. Ich war oft frustriert, wenn ich an einem Teamprojekt arbeitete, weil ein Beitrag den Build gebrochen hatte. Ich wusste nicht, ob ich schuld war oder in einigen Fällen sogar, wer schuld war. Aber ich war mehr besorgt, dass ich meinen Mitentwicklern dasselbe antun würde. Diese Erkenntnis motivierte dann, einige TDD-Strategien zu übernehmen. Unser Team hat alberne Spiele und Regeln, wie Sie nicht nach Hause gehen können, bis alle Ihre Tests bestanden sind, oder wenn Sie etwas ohne Test einreichen, müssen Sie jedem "Bier / Mittagessen / etc" kaufen und es hat TDD mehr Spaß gemacht.

Dai Bok
quelle
3

Einer der nützlichsten Aspekte beim Testen von Einheiten besteht darin, die fortlaufende Richtigkeit des bereits funktionierenden Codes sicherzustellen. Wenn Sie nach Belieben umgestalten können, lassen Sie sich von einer IDE an Fehler bei der Kompilierung erinnern, und klicken Sie dann auf eine Schaltfläche, damit Ihre Tests potenzielle Laufzeitfehler erkennen - manchmal in zuvor trivialen Codeblöcken. Dann werden Sie wahrscheinlich Ihr Team finden beginnen TDD zu schätzen. Es ist also auf jeden Fall nützlich, mit dem Testen des vorhandenen Codes zu beginnen.

Um ehrlich zu sein, habe ich mehr darüber gelernt, wie man testbaren Code schreibt, indem man versucht, geschriebenen Code zu testen, als mit TDD zu beginnen. Es kann zunächst zu abstrakt sein, wenn Sie versuchen, Verträge zu finden, die sowohl das Endziel erreichen als auch Tests ermöglichen. Wenn Sie sich jedoch den Code ansehen und sagen können: "Dieser Singleton hier verdirbt die Abhängigkeitsinjektion vollständig und macht das Testen unmöglich", beginnen Sie, ein Verständnis dafür zu entwickeln, welche Muster Ihr Testleben erleichtern.

David Berger
quelle
3

Wenn Sie keine Tests zuerst schreiben, ist dies nicht "Test Driven", sondern nur ein Test. Es hat Vorteile für sich und wenn Sie bereits eine Codebasis haben, die Tests hinzufügt, ist es sicherlich nützlich, auch wenn es nicht TDD ist, sondern nur Testen.

Beim Schreiben von Tests geht es zunächst darum, sich darauf zu konzentrieren, was der Code tun soll, bevor er geschrieben wird. Ja, Sie bekommen auch einen Test, der das macht, und es ist gut, aber einige mögen argumentieren, dass es nicht einmal der wichtigste Punkt ist.

Ich würde das Team in Spielzeugprojekten wie diesen (siehe Coding Dojo, Katas) mit TDD schulen (wenn Sie erfahrene TDD-Programmierer dazu bringen können, an einem solchen Workshop teilzunehmen, wäre es sogar noch besser). Wenn sie die Vorteile sehen, werden sie TDD für das eigentliche Projekt verwenden. Aber zwingen Sie sie in der Zwischenzeit nicht, wenn sie den Nutzen nicht sehen, werden sie es nicht richtig machen.

kriss
quelle
3

Wenn Sie vor dem Schreiben von Code Entwurfssitzungen haben oder ein Entwurfsdokument erstellen müssen, können Sie Unit-Tests als konkretes Ergebnis einer Sitzung hinzufügen.

Dies könnte dann als Spezifikation dienen, wie Ihr Code funktionieren soll. Ermutigen Sie das Pairing in der Entwurfssitzung, damit die Leute darüber sprechen, wie etwas funktionieren soll und was es in bestimmten Szenarien tun soll. Was sind die Randfälle mit expliziten Testfällen, damit jeder weiß, was zu tun ist, wenn beispielsweise ein Nullargument angegeben wird?

Nebenbei könnte aber auch BDD von Interesse sein

danswain
quelle
BDD war mir nicht bekannt. Ich muss mehr darüber lesen.
Walter
3

Sie können eine gewisse Traktion finden, indem Sie ein oder zwei Beispiele zeigen, in denen TDD dazu führt, dass weniger Code geschrieben wird. Da Sie nur Code schreiben, der für den Test erforderlich ist, ist die Versuchung, eine Goldplatte zu erstellen oder sich auf YAGNI einzulassen, leichter zu widerstehen. Code, den Sie nicht schreiben, muss nicht gewartet, überarbeitet usw. werden. Dies ist eine "echte Ersparnis", die zum Verkauf des TDD-Konzepts beitragen kann.

Wenn Sie den Wert in Bezug auf Zeit, Kosten, Code und gesparte Fehler klar nachweisen können, ist der Verkauf möglicherweise einfacher.

Michael Nash
quelle
2

Wenn Sie mit dem Erstellen von JUnit-Testklassen beginnen, können Sie beginnen. Bei vorhandenem Code ist dies der einzige Start. Nach meiner Erfahrung ist es sehr nützlich, Testklassen für vorhandenen Code zu erstellen. Wenn das Management der Ansicht ist, dass dies zu viel Zeit kostet, können Sie vorschlagen, Testklassen nur dann zu schreiben, wenn festgestellt wird, dass die entsprechende Klasse einen Fehler enthält oder bereinigt werden muss.

Für den Wartungsprozess besteht der Ansatz, um das Team über die Leitung zu bringen, darin, JUnit-Tests zu schreiben, um Fehler zu reproduzieren, bevor Sie sie beheben, d. H.

  • Fehler wird gemeldet
  • Erstellen Sie bei Bedarf eine JUnit-Testklasse
  • Fügen Sie einen Test hinzu, der den Fehler reproduziert
  • Korrigieren Sie Ihren Code
  • Führen Sie den Test aus, um anzuzeigen, dass der aktuelle Code den Fehler nicht reproduziert

Sie können erklären, dass durch "Dokumentieren" von Fehlern auf diese Weise verhindert wird, dass sich diese Fehler später wieder einschleichen. Das ist ein Vorteil, den das Team sofort erleben kann.

rsp
quelle
2

Ich habe dies in vielen Organisationen getan und festgestellt, dass der beste Weg, um TDD zu starten und zu befolgen, darin besteht, die Paarprogrammierung einzurichten. Wenn Sie jemanden haben, auf den Sie zählen können, der TDD kennt, können Sie sich trennen und mit anderen Entwicklern koppeln, um tatsächlich eine gepaarte Programmierung mit TDD durchzuführen. Wenn nicht, würde ich jemanden schulen, der Ihnen dabei hilft, bevor ich es dem Rest des Teams vorstelle.

Eine der größten Hürden bei Unit-Tests und insbesondere bei TDD besteht darin, dass Entwickler nicht wissen, wie es geht, sodass sie nicht sehen können, wie sich ihre Zeit lohnt. Auch wenn Sie zum ersten Mal anfangen, ist es viel langsamer und scheint keine Vorteile zu bieten. Es bietet Ihnen nur dann wirklich Vorteile, wenn Sie gut darin sind. Durch das Einrichten gepaarter Programmiersitzungen können Sie Entwickler schnell dazu bringen, es schnell zu lernen und schneller gut darin zu werden. Darüber hinaus können sie sofort davon profitieren, wenn Sie zusammenarbeiten.

Dieser Ansatz hat in der Vergangenheit viele Male für mich funktioniert.

John Sonmez
quelle
2

Eine leistungsstarke Möglichkeit, die Vorteile von TDD zu entdecken, besteht darin, einige vorhandene Funktionen möglicherweise aus Leistungsgründen erheblich neu zu schreiben. Indem Sie eine Reihe von Tests erstellen, die alle Funktionen des vorhandenen Codes gut abdecken, können Sie sicher sein, dass Ihre Änderungen sicher sind.

Beachten Sie, dass ich in diesem Fall über das Testen des Designs oder von Vertragstests spreche, bei denen die Details der Testimplementierung hier nicht geeignet sind. Andererseits kann TDD die Implementierung nicht per Definition testen, da sie vor der Implementierung geschrieben werden sollen.

Chris Welsh
quelle
1

TDD ist ein Tool, mit dem Entwickler besseren Code erstellen können. Ich habe das Gefühl, dass das Schreiben von testbarem Code mindestens so wertvoll ist wie die Tests selbst. Das Isolieren der IUT (Implementierung im Test) zu Testzwecken hat den Nebeneffekt, dass Ihr Code entkoppelt wird.

TDD ist nicht jedermanns Sache, und es gibt keine Magie, die ein Team dazu bringt, sich dafür zu entscheiden. Das Risiko besteht darin, dass Unit-Test-Autoren, die nicht wissen, was es wert ist, getestet zu werden, viele Tests mit geringem Wert schreiben, die für die TDD-Skeptiker in Ihrem Unternehmen Kanonenfutter darstellen.

Normalerweise mache ich automatisierte Abnahmetests nicht verhandelbar, erlaube Entwicklern jedoch, TDD so einzuführen, wie es ihnen passt. Ich habe meine erfahrenen TDDer den Rest trainieren / betreuen lassen und die Nützlichkeit über einen Zeitraum von vielen Monaten anhand von Beispielen "beweisen".

Dies ist sowohl ein sozialer / kultureller als auch ein technischer Wandel.

Doug Knesek
quelle