Ich bin ein neuer Programmierer (lerne erst seit ungefähr einem Jahr) und in meinem Ziel, besser darin zu werden, habe ich erst kürzlich etwas über TDD gelernt. Ich wollte es mir zur Gewohnheit machen, weil es mir sehr hilfreich erscheint. Ich wollte überprüfen, ob ich es richtig benutze.
Was mache ich:
- Denken Sie an eine neue Methode, die ich brauche.
- Erstellen Sie einen Test für diese Methode.
- Test nicht bestanden.
- Schreibmethode.
- Test bestehen.
- Refactor-Methode.
- Wiederholen.
Ich mache das für JEDE Methode, die ich schreibe. Gibt es eine, mit der ich mich nicht beschäftigen sollte? Später überlege ich mir normalerweise eine Möglichkeit, meine bereits vorhandenen Methoden auf eine andere Art und Weise oder in einer anderen Situation zu testen. Sollte ich diese neuen Tests durchführen, an die ich denke, oder sollte ich mich nicht darum kümmern, da jede Methode bereits einen eigenen Test hat? Kann ich meinen Code ÜBERMÄSSIG testen? Ich denke, dies ist mein Hauptanliegen.
BEARBEITEN
Auch das war etwas, was ich mich nur gefragt habe. Wäre in dieser Situation TDD erforderlich, wenn Sie so etwas wie eine grafische Benutzeroberfläche erstellen? Persönlich kann ich mir nicht vorstellen, wie ich dafür Tests schreiben würde.
Antworten:
Was Sie als Workflow bezeichnen, ist meiner Meinung nach nicht der Spirit of TDD.
Die Inhaltsangabe von Kent Becks Buch bei Amazon lautet:
Praktisches TDD
Formale automatisierte Tests, insbesondere Unit-Tests. Jede Methode jeder Klasse ist genauso schlecht wie ein Anti-Pattern und es wird nichts getestet. Es ist ein Gleichgewicht zu haben. Schreiben Sie Unit-Tests für jede
setXXX/getXXX
Methode, sie sind auch Methoden!Auch Tests können helfen, Zeit und Geld zu sparen. Vergessen Sie jedoch nicht, dass die Entwicklung Zeit und Geld kostet und dass sie Code sind, sodass die Wartung Zeit und Geld kostet. Wenn sie aufgrund mangelnder Wartung verkümmern, werden sie mehr zu einer Verbindlichkeit als zu einem Vorteil.
Wie alles in diesem Sinne gibt es ein Gleichgewicht, das nur von Ihnen selbst definiert werden kann. Jedes Dogma, egal wie, ist wahrscheinlich mehr falsch als richtig.
Eine gute Metrik ist Code, der für die Geschäftslogik von entscheidender Bedeutung ist und aufgrund sich ändernder Anforderungen häufig geändert wird. Diese Dinge erfordern formale Tests, die automatisiert sind, was eine große Rendite bedeutet.
Es wird Ihnen sehr schwer fallen, viele professionelle Läden zu finden, die auf diese Weise funktionieren. Aus geschäftlichen Gründen ist es einfach nicht sinnvoll, Geld auszugeben, um Dinge zu testen, die sich nach einem einfachen Rauchtest für alle praktischen Zwecke nicht ändern. Das Schreiben formaler automatisierter Komponententests für
.getXXX/.setXXX
Methoden ist ein hervorragendes Beispiel für diese völlige Zeitverschwendung.Siehe auch diese Antwort .
quelle
setXXX/getXXX
werden überhaupt nicht benötigt :)Du bist sehr nah dran. Versuchen Sie, auf diese etwas andere Weise zu denken.
Erstellen Sie nicht automatisch Getter und Setter für jede Eigenschaft . Denken Sie nicht an eine ganze Methode und schreiben Sie den Test (s) alle Funktionen abzudecken . Versuchen Sie, die Eigenschaften in der Klasse zu kapseln und Methoden zu schreiben, um das gewünschte Verhalten zu erzielen. Lassen Sie Ihre Methoden zu einem guten Design werden, anstatt zu versuchen, sie im Voraus zu planen. Denken Sie daran, dass TDD ein Entwurfsprozess und kein Testprozess ist. Der Vorteil gegenüber anderen Entwurfsprozessen besteht darin, dass nicht mehr ein Stück Papier in den Papierkorb geworfen wird, sondern eine Reihe automatisierter Regressionstests.
Denken Sie auch an die drei TDD-Regeln von Onkel Bob .
quelle
Einige Dinge, die man zu den Antworten anderer hinzufügen kann:
Es gibt so etwas wie überprüfen. Sie möchten sicherstellen, dass sich Ihre Komponententests so wenig wie möglich überlappen. Es hat keinen Sinn, dass mehrere Tests dieselben Bedingungen in demselben Code überprüfen. Wenn Sie andererseits Ihren Produktionscode überarbeiten und viele Tests haben, die sich mit diesem Abschnitt überschneiden, müssen Sie alle diese Tests korrigieren. Wenn sie sich nicht überlappen, unterbricht eine Änderung höchstens einen Test.
Nur weil Sie sich eine bessere Möglichkeit ausgedacht haben, einen Test zu schreiben, würde ich nicht dorthin zurückkehren und anfangen, ihn neu zu schreiben. Dies geht auf die Personen zurück, die weiterhin dieselbe Klasse / Funktion schreiben und umschreiben, weil sie versuchen, sie zu perfektionieren. Es wird niemals perfekt sein, also mach weiter. Wenn Sie eine bessere Methode entdecken, behalten Sie diese im Hinterkopf (oder ergänzen Sie die Kommentare des Tests). Wenn Sie das nächste Mal dort sind und den unmittelbaren Vorteil eines Wechsels auf den neuen Weg sehen, ist dies die Zeit für eine Umgestaltung. Andernfalls, wenn die Funktion fertig ist und Sie fortfahren und alles funktioniert, lassen Sie es funktionieren.
TDD konzentriert sich darauf, einen unmittelbaren Wert zu liefern und nicht nur sicherzustellen, dass jede Funktion testbar ist. Wenn Sie Funktionen hinzufügen, fragen Sie zunächst, was der Client benötigt. Definieren Sie dann eine Schnittstelle, um dem Client das zu geben, was er benötigt. Implementieren Sie dann alles, was zum Bestehen des Tests erforderlich ist. TDD ähnelt fast dem Testen von Anwendungsszenarien (einschließlich aller "Was-wäre-wenn"), anstatt einfach öffentliche Funktionen zu codieren und jede einzelne zu testen.
Sie haben nach dem Testen des GUI-Codes gefragt. Schlagen Sie die Muster "Humble Dialog" und "MVVM" nach. Die Idee dahinter ist, dass Sie eine Reihe von "Ansichtsmodell" -Klassen erstellen, die eigentlich keine UI-spezifische Logik haben. Diese Klassen verfügen jedoch über die gesamte Geschäftslogik, die normalerweise Teil Ihrer Benutzeroberfläche ist, und diese Klassen sollten zu 100% testbar sein. Was bleibt, ist eine sehr dünne UI-Shell, und ja, normalerweise bleibt diese Shell ohne Testabdeckung, aber zu diesem Zeitpunkt sollte sie fast keine Logik haben.
Wenn Sie einen großen Teil des vorhandenen Codes haben, sollten Sie, wie wenige andere vorgeschlagen haben, nicht überall Unit-Tests hinzufügen. Es wird ewig dauern und 80% der Klassen, die stabil sind und sich in naher (oder in naher) Zukunft nicht ändern werden, können Sie nicht von Unit-Tests profitieren. Für neue Arbeiten empfinde ich die Verwendung der TDD-Entwicklung mit ALLEM Code jedoch als äußerst vorteilhaft. Wenn Sie fertig sind, erhalten Sie nicht nur eine Suite mit automatisierten Tests, sondern die eigentliche Entwicklung hat auch enorme Vorteile:
quelle
Es gibt einige Methoden, die nicht getestet werden, nämlich diese Tests. Für einige Tests, die hinzugefügt werden, nachdem der ursprüngliche Code geschrieben wurde, ist jedoch etwas zu sagen, wie z. B. Randbedingungen und andere Werte, sodass möglicherweise mehrere Tests mit einer einzelnen Methode durchgeführt werden.
Zwar können Sie Ihren Code übertesten, doch in der Regel möchte jemand jede mögliche Permutation von Eingaben testen, was nicht ganz so klingt, wie Sie es tun. Wenn Sie beispielsweise eine Methode haben, die ein Zeichen aufnimmt, schreiben Sie einen Test für jeden möglichen Wert, der eingegeben werden könnte? Das wäre der Punkt, an dem Sie zu Übertests kommen würden, IMO.
quelle
Im Allgemeinen machst du es richtig.
Tests sind Code. Wenn Sie den Test verbessern können, müssen Sie ihn überarbeiten. Wenn Sie der Meinung sind, dass ein Test verbessert werden kann, ändern Sie ihn. Haben Sie keine Angst, einen Test durch einen besseren zu ersetzen.
Ich empfehle, beim Testen Ihres Codes nicht anzugeben, wie der Code das tun soll, was er tut. Tests sollten sich die Ergebnisse der Methoden ansehen. Dies wird beim Refactoring helfen. Einige Methoden müssen nicht explizit getestet werden (dh einfache Getter und Setter), da Sie diese verwenden, um die Ergebnisse anderer Tests zu überprüfen.
quelle
Meine Meinung zu TDD ist, dass das Tool eine Welt von Point-and-Click-Entwicklern geschaffen hat. Nur weil die Tools für jede Methode einen Teststub erstellen, müssen Sie nicht für jede Methode Tests schreiben. Einige Leute benennen TDD in BDD (Behaviour Driven Development) um, wo die Tests viel umfangreicher sind und das Verhalten der Klasse testen sollen, nicht jede fummelige Methode.
Wenn Sie Ihre Tests so entwerfen, dass die Klasse so getestet wird, wie sie verwendet werden soll, erhalten Sie einige Vorteile, insbesondere wenn Sie Tests schreiben, die etwas mehr als jede Methode erfordern, insbesondere wenn Sie die Interaktion dieser Tests testen Methoden. Ich nehme an, Sie können sich das so vorstellen, als würden Sie Tests für eine Klasse schreiben, anstatt Methoden. In jedem Fall müssen Sie noch 'Akzeptanztests' schreiben, die die Kombination von Methoden anwenden, um sicherzustellen, dass es keine Widersprüche oder Konflikte bei der gemeinsamen Verwendung gibt.
Verwechseln Sie TDD nicht mit dem Testen - das ist es nicht. TDD ist so konzipiert, dass Sie Code schreiben, um Ihre Anforderungen zu erfüllen, und nicht, um die Methoden zu testen. Es ist ein subtiler, aber wichtiger Punkt, der oft für Leute verloren geht, die blindlings Testcode für jede Methode schreiben. Sie sollten Tests schreiben, die sicherstellen, dass Ihr Code das tut, was Sie möchten, und nicht, dass der von Ihnen geschriebene Code wie vorgesehen funktioniert.
Rechts finden Sie einige gute Links zu BDD v TDD. Schau sie dir an.
quelle
Wenn Sie anfangen , TDD zu lernen, sollten Sie blindlings dem dogmatischen Ansatz folgen, keine einzige Codezeile zu schreiben, außer einen nicht bestandenen Test zu bestehen und nur genügend Tests zu schreiben, um zu scheitern (und dies aus dem richtigen / erwarteten Grund). .
Sobald Sie gelernt haben, worum es bei TDD geht, können Sie entscheiden, dass bestimmte Dinge keinen Test wert sind. Dies ist der gleiche Ansatz, den Sie für alles verfolgen sollten, und die japanischen Kampfkünste nennen dies " Shuhari ". (Der Link erklärt auch, wie man die Lernstufen ohne einen Lehrer durchlaufen kann, was, wie ich vermute, die meisten Menschen lernen müssen.)
quelle
Ich glaube, dass Sie übertesten.
Ich praktiziere seit vielen Jahren TDD, und meiner Erfahrung nach erhalten Sie bei einer effektiven Durchführung von TDD zwei Hauptvorteile:
Geben Sie schnelles Feedback
Insbesondere bei dynamischen Sprachen kann ich die entsprechenden Tests in weniger als einer Sekunde ausführen. Und ich habe Dateisystem-Beobachter, die diese Tests automatisch ausführen, wenn eine Quelldatei auf der Festplatte geändert wird. Somit habe ich praktisch keine Wartezeit auf Tests und weiß sofort, ob der von mir geschriebene Code wie erwartet funktioniert hat. Somit führt TDD zu einer sehr effizienten Arbeitsweise.
Refactoring aktivieren
Wenn Sie über eine gute Testsuite verfügen, können Sie sicher umgestalten, indem Sie neue Einblicke in die Gestaltung des Systems gewinnen.
Mit einer guten Testsuite können Sie die Verantwortung in Ihrem Code verschieben und trotzdem darauf vertrauen, dass der Code nach dem Verschieben wie erwartet funktioniert. Und Sie sollten in der Lage sein, dies mit kleinen Änderungen am Testcode zu tun.
Wenn Sie Tests für jede Methode in Ihrem System schreiben, besteht die Wahrscheinlichkeit, dass Sie Ihren Code nicht einfach umgestalten können. Jeder Umgestalter Ihres Codes erfordert massive Änderungen am Testcode. Und können Sie sogar sicher sein, dass der Testcode weiterhin wie erwartet funktioniert? Oder haben Sie versehentlich einen Fehler in den Testcode eingefügt, der folglich zu einem Fehler im Produktionscode führt?
Wenn Sie jedoch, wie auch in vorgeschlagen pdr Antwort , konzentrieren sich auf das Verhalten statt Methoden beim Schreiben von Tests, haben Sie Tests , die viel weniger Änderungen erforderlich werden , wenn das System Refactoring.
Oder wie Ian Cooper in dieser Präsentation sagt (ich zitierte aus dem Gedächtnis, könnte also nicht richtig zitiert sein):
quelle
Sie sollten jede öffentliche Methode testen .
Der Haken dabei ist, dass Sie wahrscheinlich zu viele Informationen preisgeben, wenn Ihre öffentlichen Methoden sehr klein sind. Die übliche Praxis, jede Eigenschaft als
getXXX()
tatsächlich verfügbar zu machen, bricht die Kapselung.Wenn Ihre öffentlichen Methoden tatsächlich das Verhalten der Klasse sind, sollten Sie sie testen. Wenn nicht, sind sie keine guten öffentlichen Methoden.
EDIT: Die Antwort von pdr ist viel vollständiger als meine.
quelle