Wie verwende ich Unit-Tests bei Verwendung von BDD?

17

Ich versuche BDD zu verstehen. Ich habe einige Artikel gelesen und wie ich verstanden habe, ist BDD "der nächste Schritt" von TDD. Ich sage das, weil ich beide sehr ähnlich finde und wie ich in diesem Artikel lesen konnte , wurde BDD als Verbesserung von TDD geboren. Großartig, ich mag die Idee wirklich.

Es gibt einen praktischen Punkt, den ich nicht verstehe, dachte ich: Es gibt eine .feature-Datei, in die der BA das gesamte erwartete Verhalten schreibt, das das System haben würde. Als BA hat er keine Ahnung, wie das System aufgebaut ist, also werden wir so etwas schreiben:

Szenario 1: Konto ist im Guthaben

Dazu wird das Konto gutgeschrieben

Und die Karte ist gültig

Und der Spender enthält Bargeld

Wenn der Kunde Bargeld verlangt

Stellen Sie dann sicher, dass das Konto belastet wird, und stellen Sie sicher, dass Bargeld ausgegeben wird

Und stellen Sie sicher, dass die Karte zurückgegeben wird

Ok, das ist großartig, aber es gibt viele Teile des Systems, die zusammenarbeiten, so dass es passieren kann (denken Sie an Account obj, Dispenser obj, Customer obj und so weiter). Für mich sieht das wie ein Integrationstest aus.

Ich hätte gerne Unit Tests. Wie teste ich den Code, der prüft, ob der Spender Geld hat? Oder dass das Geld ausgegeben wird? Oder dass das Konto bei Bedarf belastet wird? Wie kann ich Unit-Tests mit "BA Created" -Tests mischen?

JSBach
quelle
Dafür sind Mocks und Stubs gedacht: um die zu prüfenden Teile zu isolieren.
Robert Harvey
Entschuldigung, ich verstehe es nicht. Du meinst, ich sollte den Spender verspotten? Wie würde ich es testen?
JSBach,
Wenn Sie den Spender testen, verspotten Sie das Konto, die Karte und den Kunden.
Robert Harvey
3
Warum möchten Sie Komponententests und von der BA erstellte Tests mischen? Verwenden Sie TDD als Technik, um Komponententests für einzelne Teile Ihrer Software zu erstellen, und fügen Sie zusätzliche Tests hinzu, um die Anforderungen aus Sicht der BA zu testen (nennen Sie die letzteren Integrationstests, wenn Sie möchten). Wo siehst du einen Widerspruch?
Doc Brown
@DocBrown: Mit "natürlich auftauchen" meine ich, dass einige TDD'er glauben, dass ein Software-Design aus den Unit-Tests als "Rot-Grün-Refaktor" hervorgehen wird. Eine laufende Chat-Unterhaltung zu dieser Frage findet in The Whiteboard statt .
Robert Harvey

Antworten:

27

Behaviour Driven Development und Test Driven Development sind komplementär, aber kein Ersatz für einander.

Wie sich die Anwendung "verhält", wird in Abnahmetests beschrieben. Dies sind laut BDD die in Cucumber geschriebenen Funktionen und Szenarien.

Die Details zur Funktionsweise der einzelnen kleinen Komponenten sind in Unit Tests beschrieben. Die Ergebnisse der Komponententests unterstützen die Szenarien, die Sie in Cucumber schreiben.

Stellen Sie sich den Prozess für den Bau eines Autos vor.

Zunächst entwickelt das Produktteam seine Ideen und fasst sie schließlich zu Nutzungsszenarien zusammen:

Scenario: Starting the car
    Given I am standing in front of the drivers door
    When I open the door
    Then the door should lift up DeLorean-style (yeah, baby!)
    When I get into the car
    And turn the key
    Then the engine roars to life

Ich weiß, dass dieses Szenario ein bisschen albern klingt, aber es ist eine sehr hohe Anforderung, die sich auf Produkte und Endbenutzer konzentriert. Das Öffnen der Tür, das Drehen des Schlüssels und das Starten des Motors erfordern eine Vielzahl von Komponenten, die zusammenarbeiten. Dieser eine Test reicht nicht aus, um sicherzustellen, dass das Fahrzeug ordnungsgemäß funktioniert. Sie müssen den Anlasser, die Batterie, die Lichtmaschine, den Schlüssel und den Zündschalter testen - und die Liste geht weiter -, um ins Auto zu steigen und es zu starten. Jede dieser Komponenten benötigt ihre eigenen Tests.

Das obige Szenario ist ein "Big Picture" -Test. Jede Komponente des Fahrzeugs benötigt "Small Picture" -Tests, um sicherzustellen, dass sie im Ganzen einwandfrei funktionieren.

Das Erstellen und Testen von Software ist in vielerlei Hinsicht identisch. Sie entwerfen von oben nach unten und bauen dann von unten nach oben. Warum eine Tür, die sich anhebt, wenn Sie nicht einmal den Motor starten können? Warum einen Anlasser haben, wenn Sie keine Batterie haben?

Ihr Produktteam erstellt die Abnahmetests und konkretisiert sie in Cucumber. Dies gibt Ihnen das "Big Picture". Jetzt muss das Entwicklungsteam die richtigen Komponenten entwerfen und festlegen, wie sie sich gegenseitig beeinflussen. Testen Sie sie dann einzeln. Dies sind Ihre Komponententests.

Sobald die Komponententests bestanden sind, beginnen Sie mit der Implementierung der Gurkenszenarien. Sobald diese vergangen sind, haben Sie geliefert, was das Produktteam gefragt hat.

Greg Burghardt
quelle
Gibt es eine Möglichkeit, diese "Big Picture" -Tests mit "Small Picture" -Tests zu verknüpfen? Ich meine, wenn sich Funktionen offiziell ändern (sagen wir, dass sich das Gurkenszenario ändert), gibt es eine Möglichkeit, diese Änderung auf die Low-End-Tests abzubilden (sagen wir, Junit-Tests, die für dieses bestimmte Gurkenszenario gelten)?
Srikanth
Sie können Hilfsmethoden und benutzerdefinierte Zusicherungen für Ihre Tests "Großes Bild" und "Kleines Bild" verwenden. Diese umfassen jedoch höchstwahrscheinlich unterschiedliche Einstellungen zum Testen bestimmter Codeeinheiten.
Nick McCurdy
[...] die laut BDD die in Cucumber geschriebenen Features und Szenarien wären. Sie vereinen Prinzipien und Werkzeuge.
jub0bs
Ok, der Wortlaut ist ein wenig abweichend, aber der Punkt ist, dass das Verhalten einer Anwendung in den Funktionen und Szenarien erfasst wird.
Greg Burghardt
9

Ich versuche BDD zu verstehen. Ich habe einige Artikel gelesen und verstanden, dass BDD "der nächste Schritt" von TDD ist. Ich sage das, weil ich beide sehr ähnlich finde und wie ich in diesem Artikel lesen konnte, wurde BDD als Verbesserung von TDD geboren.

Nein, BDD ist nicht "der nächste Schritt" von TDD. Es ist TDD. Genauer gesagt handelt es sich um eine Neuformulierung von TDD.

Die Entwickler von BDD stellten fest, dass die größte Hürde für das Verständnis, dass es bei TDD nicht um Tests, sondern um Verhaltensspezifikationen geht, darin besteht, dass sich die gesamte TDD-Terminologie auf Tests und nicht auf Verhaltensspezifikationen bezieht. Es ist, als würde man versuchen, nicht an einen rosa Elefanten zu denken, wenn jemand zu Ihnen sagt: "Versuchen Sie nicht, an einen rosa Elefanten zu denken." Elefant, rosa Elefant "in Ihrem Ohr.

Also formulierten sie TDD in Bezug auf die Verhaltensspezifikation neu. "Tests" und "Testfälle" sind jetzt "Beispiele", "Einheiten" sind "Verhalten", "Behauptungen" sind "Erwartungen" und so weiter.

Die Methodik ist jedoch immer noch dieselbe. Sie beginnen mit einem Abnahmetest (ich meine "Feature"), zoomen in einen Unit-Test (ich meine "Beispiel"), zoomen wieder aus usw.

Ich hätte gerne Unit Tests. Wie teste ich den Code, der prüft, ob der Spender Geld hat? Oder dass das Geld ausgegeben wird? Oder dass das Konto bei Bedarf belastet wird? Wie kann ich Unit-Tests mit "BA Created" -Tests mischen?

Genauso wie bei TDD. Sie können Ihre Features und Beispiele in verschiedenen Frameworks (z. B. Cucumber und RSpec) oder sogar in verschiedenen Sprachen (z. B. Schreiben von Beispielen für ein C-Projekt in C und Features in FIT / Fitnesse) schreiben. Sie können für beide ein einziges Feature-Framework verwenden ( Beispiel: Schreiben von Beispielen und Funktionen in Cucumber) oder Sie können ein einzelnes Beispiel-Framework für beide verwenden (z. B. Schreiben von beiden in RSpec). Sie müssen nicht einmal ein Framework verwenden.

Ein Beispiel für TDD-done-right (das mit BDD identisch ist), das nur ein einziges Framework verwendet, ist JUnit selbst, das eine Mischung aus Komponententests (Beispielen) und Funktions- / Integrationstests (Features) enthält, die alle in JUnit selbst geschrieben wurden.

Ich glaube, Kent Beck nennt das "Zoomen". Beginnen Sie auf hoher Ebene, "zoomen" Sie in die Details und kehren Sie dann wieder zurück.

Jörg W. Mittag
quelle
1

Haftungsausschluss: Ich bin kein BDD-Experte, aber ich versuche, Ihnen meine Meinung zu dem Artikel zu sagen, auf den Sie verlinkt haben.

TDD ist eine Implementierungstechnik - Sie schreiben zuerst einen Test, implementieren dann die Methode, führen Ihren Test aus, refaktorieren und fügen weitere Tests für dieselbe Methode oder für eine neue Methode hinzu. TDD definiert eigentlich keine Regeln für die Auswahl von Klassen- oder Methodennamen, das liegt bei Ihnen. TDD sagt Ihnen auch nicht "wenn Sie fertig sind".

Wenn Sie also einen Test für eine neue Methode schreiben, müssen Sie einen Methodennamen auswählen - und genau an diesem Punkt kommt BDD ins Spiel. Wählen Sie die Methodennamen anhand der Geschäftsbegriffe aus dem obigen Szenario aus und wählen Sie sie so aus, dass sie beschreiben Nach dem Verhalten deiner Klasse machst du BDD. Wenn Sie sich die Frage stellen, ob weitere Tests hinzugefügt werden müssen, können Sie die von Ihrem BA vorgegebenen Szenarien überprüfen und überprüfen, ob Sie alle erforderlichen Teile vollständig implementiert haben. Wenn nicht, müssen Sie weitere Tests hinzufügen.

Der Autor des Artikels schlägt außerdem vor, bei der Auswahl der Namen Ihrer Tests ein stärker verhaltensbezogenes Benennungsschema zu verwenden. Deshalb schlägt er vor, JUnit durch ein Tool zu ersetzen, das nicht auf einem Benennungsschema basiert, mit dem jeder Testfall beginnen muss der Name "Test". Obwohl ich JBehave nicht kenne, denke ich, dass dies der Hauptunterschied zwischen diesem Tool und Junit ist.

Darüber hinaus sind die BDD-Szenarien auch eine Blaupause für Integrationstests, die Sie normalerweise hinzufügen, nachdem Sie die Methodennamen von TDD ausgearbeitet und eine angemessene Anzahl von Komponententests hinzugefügt haben.

Nach meinem Verständnis ist TDD ein Instrument, das Sie als Teil von BDD verwenden können, und BDD hilft Ihnen, die richtigen Tests zu schreiben und ihnen bessere Namen zu geben.

Doc Brown
quelle
Um es kurz zu machen: Junit unterstützt die Benennung Ihrer Tests. Sie müssen nur eine @ Test-Anmerkung verwenden. Es kann jedoch sein, dass dies im Jahr 2003 noch nicht geschehen ist.
soru
@soru Bereits 2003 hat es das Wort "Test" durchgesetzt.
Lunivore,
Der Autor des Artikels ist Dan North, der das Konzept überhaupt erst entwickelt hat. Eines der Dinge, die ihm aufgefallen sind, ist, dass das Wort "Test" uns veranlasst, unsere Implementierung (Lösungsdomäne) zu testen, wohingegen das Erkunden und Definieren von Tests uns wirklich in der Problemdomäne halten sollte. Dan hat BDD als "das beschrieben, was TDD sein sollte". Lesen Sie dies für weitere Informationen: dannorth.net/2012/05/31/bdd-is-like-tdd-if
Lunivore