Ich verstehe die testgetriebene Entwicklung so weit, dass Sie nur dann produktiven Code schreiben dürfen, wenn Sie einen fehlerhaften (roten) Unit-Test haben. Darauf aufbauend habe ich die Frage, ob der testgetriebene Ansatz auch auf andere Testformen anwendbar ist.
41
Antworten:
Alles, was TDD von Ihnen verlangt, ist, dass Sie einen fehlerhaften Test schreiben und dann Ihren Code so ändern, dass er bestanden wird.
Typischerweise sind "Komponententests" klein und schnell und testen einen Teil Ihres Codes isoliert. Da sie schnell sind, ist auch die Rot / Grün / Refaktor-Schleife schnell. Sie leiden jedoch nur unter dem isolierten Testen von Teilen. Sie benötigen also auch andere Tests (Integration, Akzeptanz usw.). Es ist immer noch eine gute Praxis, die gleichen Prinzipien zu befolgen: Schreiben Sie einen fehlerhaften Test und ändern Sie den Code, damit er funktioniert. Beachten Sie jedoch, dass sie in der Regel langsamer sind, was sich auf die Zykluszeit von Rot / Grün / Refaktor auswirken kann.
quelle
Der rot-grüne Refaktorzyklus basiert auf einem sehr soliden Prinzip:
Nur Vertrauenswürdigkeitstests, bei denen Sie sowohl Bestanden als auch Nichtbestanden festgestellt haben.
Ja, das funktioniert auch mit automatisierten Integrationstests. Auch manuelle Tests. Heck, es funktioniert auf Autobatterietestern. So testen Sie den Test.
Einige denken, Unit-Tests decken das Kleinste ab, was getestet werden kann. Manche denken an alles, was schnell zu testen ist. TDD ist mehr als nur der Rot-Grün-Refaktor-Zyklus, aber dieser Teil hat eine Reihe von Tests: Es sind nicht die Tests, die Sie idealerweise einmal ausführen werden, bevor Sie eine Sammlung von Änderungen einreichen. Es sind die Tests, die Sie jedes Mal ausführen, wenn Sie Änderungen vornehmen. Für mich sind das deine Unit-Tests.
quelle
Ja, und ein bekannter Ansatz, der dies tut, ist die verhaltensorientierte Entwicklung . Die Tests, die aus der formalen Spezifikation in BDD generiert werden, können als "Komponententests" bezeichnet werden. Sie sind jedoch in der Regel nicht so niedrig wie bei echten TDD. Sie passen wahrscheinlich besser zum Begriff "Abnahmetests".
quelle
Nein. Sie dürfen nur den einfachsten Code schreiben, um die Meldung des Tests zu ändern. Es sagt nichts über welche Art von Test.
In der Tat werden Sie wahrscheinlich damit beginnen, einen fehlerhaften (roten) Abnahmetest für ein Abnahmekriterium zu schreiben. Genauer gesagt, Sie schreiben den einfachsten Abnahmetest, der möglicherweise fehlschlagen könnte. Anschließend führen Sie den Test aus, beobachten, wie er fehlschlägt, und stellen sicher, dass er aus dem richtigen Grund fehlschlägt. Dann schreiben Sie einen fehlgeschlagenen Funktionstest für einen Teil der Funktionalität dieses Akzeptanzkriteriums. Wieder schreiben Sie den einfachsten Funktionstest, der möglicherweise fehlschlägt. Führen Sie ihn aus, beobachten Sie, wie er fehlschlägt, und überprüfen Sie, ob er aus dem richtigen Grund fehlschlägt. Dann schreiben Sie einen fehlgeschlagenen Komponententest, den einfachsten Komponententest, der möglicherweise fehlschlägt. Führen Sie ihn aus, und beobachten Sie, ob er aus dem richtigen Grund fehlschlägt.
Jetzt schreiben Sie den einfachsten Produktionscode, der möglicherweise die Fehlermeldung ändern könnte. Führen Sie den Test erneut aus, und stellen Sie sicher, dass sich die Fehlermeldung geändert hat, dass sich die Richtung geändert hat und dass der Code die Nachricht aus dem richtigen Grund geändert hat. (Im Idealfall sollte die Fehlermeldung inzwischen verschwunden sein und der Test sollte bestanden werden. Meistens ist es jedoch besser, kleine Schritte zu unternehmen, um die Meldung zu ändern, anstatt zu versuchen, den Test in einem Durchgang zu bestehen. Dies ist der Grund warum Entwickler von Test-Frameworks so viel Aufwand mit ihren Fehlermeldungen betreiben!)
Sobald Sie den Komponententest bestanden haben, überarbeiten Sie Ihren Produktionscode unter dem Schutz Ihrer Tests. (Beachten Sie, dass zu diesem Zeitpunkt der Abnahmetest und der Funktionstest immer noch fehlschlagen, aber das ist in Ordnung, da Sie nur einzelne Einheiten umgestalten, die durch Einheitentests abgedeckt werden.)
Jetzt erstellen Sie den nächsten Komponententest und wiederholen diesen, bis auch der Funktionstest bestanden ist. Unter dem Schutz des Funktionstests können Sie jetzt Refactorings über mehrere Einheiten hinweg durchführen.
Dieser mittlere Zyklus wird nun wiederholt, bis der Abnahmetest erfolgreich abgeschlossen wurde. Anschließend können Sie Refactorings im gesamten System durchführen.
Nun wählen Sie das nächste Akzeptanzkriterium und der äußere Zyklus beginnt erneut.
Kent Beck, der "Entdecker" von TDD (er mag den Begriff "Erfinder" nicht, er sagt, die Leute haben das die ganze Zeit gemacht, er hat ihm nur einen Namen gegeben und ein Buch darüber geschrieben), verwendet eine Analogie aus der Fotografie und nennt dies "Vergrößern und Verkleinern".
Hinweis: Sie benötigen nicht immer drei Teststufen. Vielleicht brauchst du manchmal mehr. Oft brauchen Sie weniger. Wenn Ihre Funktionen klein sind und Ihre Funktionstests schnell sind, können Sie ohne (oder mit weniger Komponententests) auskommen. Häufig benötigen Sie nur Abnahmetests und Unit-Tests. Oder Ihre Akzeptanzkriterien sind so feinkörnig, dass es sich bei Ihren Akzeptanztests um Funktionstests handelt.
Kent Beck sagt, wenn er einen schnellen, kleinen und gezielten Funktionstest hat, schreibt er zuerst die Komponententests, lässt die Komponententests den Code fahren und löscht dann (einige) die Komponententests erneut, die den Code abdecken, der auch ist abgedeckt durch den schnellen Funktionstest. Denken Sie daran: Testcode ist auch Code, der gewartet und überarbeitet werden muss. Je weniger es gibt, desto besser!
Sie wenden TDD nicht wirklich auf Tests an. Sie wenden es auf Ihren gesamten Entwicklungsprozess an. Das ist es, was der "getriebene" Teil von Test- Driven- Development bedeutet: Ihre gesamte Entwicklung wird von Tests getrieben. Die Tests nicht nur den Code fahren Sie schreiben, sie auch fahren , was Code zu schreiben, neben welchem Code zu schreiben. Sie bestimmen Ihr Design. Sie sagen dir, wann du fertig bist. Sie sagen dir, woran du als nächstes arbeiten sollst. Sie informieren Sie über Designfehler in Ihrem Code (wenn Tests schwer zu schreiben sind).
Keith Braithwaite hat eine Übung erstellt, die er TDD nennt, als ob Sie es gemeint hätten . Es besteht aus einer Reihe von Regeln (basierend auf den drei TDD-Regeln von Onkel Bob Martin , aber viel strenger), die Sie genau befolgen müssen und die Sie dazu bringen sollen, TDD strenger anzuwenden. Es funktioniert am besten mit der Paarprogrammierung (damit Ihr Paar sicherstellen kann, dass Sie nicht gegen die Regeln verstoßen) und einem Lehrer.
Die Regeln sind:
Diese Regeln sind für die Ausübung von TDD gedacht. Sie sind nicht dafür gedacht, TDD tatsächlich in der Produktion auszuführen (obwohl nichts Sie davon abhält, es auszuprobieren). Sie können sich frustrierend fühlen, weil es manchmal so scheint, als ob Sie Tausende winziger kleiner Schritte machen, ohne wirklich Fortschritte zu machen.
quelle
TDD ist keineswegs auf das beschränkt, was die traditionelle Software Testing-Community "Unit Testing" nennt. Dieses sehr häufige Missverständnis ist das Ergebnis von Kent Becks unglücklicher Überfrachtung des Begriffs "Einheit" bei der Beschreibung seiner TDD-Praxis. Was er mit "Komponententest" meinte, war ein Test, der isoliert ablief. Es ist nicht abhängig von anderen Tests. Bei jedem Test muss der erforderliche Status festgelegt und anschließend eine Bereinigung durchgeführt werden. In diesem Sinne ist ein Einheitentest im TDD-Sinne eine Einheit. Es ist in sich geschlossen. Es kann von selbst oder zusammen mit einem anderen Komponententest in beliebiger Reihenfolge ausgeführt werden.
Literaturhinweis : "Test Driven Development By Example" von Kent Beck
Kent Beck beschreibt, was er unter „Komponententest“ versteht, in Kapitel 32 - Beherrschen von TDD
quelle
Ich habe keine Bücher darüber gelesen und folge auch nicht ständig den "normalen" TDD-Praktiken, aber in meinen Augen besteht der Hauptpunkt der TDD-Philosophie, der ich voll und ganz zustimme, darin, dass Sie zuerst den Erfolg definieren müssen . Dies ist auf jeder Designebene wichtig, ab "Was ist das Ziel dieses Projekts?" zu "Was sollen die Ein- und Ausgänge dieser kleinen Methode sein?"
Es gibt viele Möglichkeiten, um diese Definition von Erfolg zu verwirklichen. Besonders für Low-Level-Methoden mit potenziell vielen Randfällen ist es nützlich, Tests in Code zu schreiben. Für einige Abstraktionsebenen kann es hilfreich sein, einfach eine kurze Notiz über das Ziel des Moduls oder was auch immer zu schreiben oder sich selbst zu überprüfen (oder einen Mitarbeiter zu fragen), ob alles Sinn macht und sich in einem befindet logischer Ort. Manchmal ist es hilfreich, einen Integrationstest in Code zu beschreiben (und das hilft natürlich, ihn zu automatisieren), und manchmal ist es hilfreich, nur einen angemessenen Schnelltestplan zu definieren, mit dem Sie sicherstellen können, dass alle Systeme auf Ihre Art und Weise zusammenarbeiten erwarten.
Unabhängig von den spezifischen Techniken oder Tools, die Sie verwenden, ist meiner Meinung nach das Wichtigste, was Sie von der TDD-Philosophie abbringen sollten, dass der Erfolg zuerst definiert wird. Ansonsten wirfst du den Pfeil und malst dann das Bullauge überall herum, wo es zufällig gelandet ist.
quelle
Im Vortrag Test-Driven Development: Dies ist nicht das, was wir gemeint haben. Steve Freeman zeigt die folgende Folie des TDD-Gesamtüberblicks (siehe Bild unten, Antwort). Dies beinhaltet einen Schritt "Schreiben eines fehlgeschlagenen End-to-End-Tests" , gefolgt von "Schreiben eines fehlgeschlagenen Unit-Tests". (Klicken zum Vergrößern, oben rechts)
Nein, in TDD sind die Tests nicht immer Komponententests.
Und ja, Sie können (und sollten) mit einem übergeordneten End-to-End-Test beginnen, der fehlschlägt, bevor Sie Ihren ersten Komponententest schreiben. Dieser Test beschreibt das Verhalten, das Sie erreichen möchten. Dies erzeugt eine Abdeckung auf mehr Ebenen der Testpyramide . Adrian Sutton erläutert die Erfahrungen von LMAX, die zeigen, dass End-to-End-Tests eine große und wertvolle Rolle spielen können .
quelle
Nein, es kann aus einem einfachen praktischen Grund nicht auf andere Arten von Tests angewendet werden: Die Ausführung anderer Arten von Tests dauert zu lange.
Ein typischer TDD-Zyklus ist: Fehler beim Schreiben, Implementieren, Refactor-Code. Zwischenschritte sind das Erstellen und Ausführen von Tests, und diese müssen blitzschnell sein. Wenn dies nicht der Fall ist, werden die Schritte übersprungen, und Sie führen keine TDD mehr durch.
quelle