Die Programmierer von heute verwenden in ihrer täglichen Arbeit immer mehr agile Praktiken. Selbst Projekte, die dem Standard-Lebenszyklus der Software-Entwicklung folgen, können von der Anpassung dieser Methoden profitieren. Automatisches Testen und TDD bringen mehr Vertrauen in unsere Arbeit, erleichtern die Implementierung von Änderungen an bestehenden Funktionen und führen oft zu einem besseren Code-Design. Aber das reicht jetzt nicht mehr aus. Wir müssen die Vorteile von Tests bis an die Grenzen ausreizen, und BDD ermöglicht dies. BDD baut auf TDD auf und fügt dessen Praktiken eine Menge Wert hinzu. Es bringt eine allgegenwärtige Sprache in das Projekt und ermöglicht eine bessere Kommunikation zwischen Kunden und Entwicklern. Es bietet viele Vorteile für Projektmanager und -leiter, macht aber auch das Leben eines Entwicklers sehr viel einfacher. Durch die Einhaltung der BDD-Prinzipien erhalten wir klare Anforderungen, die Tests sind leichter zu verstehen und können als Dokumentation dienen. BDD verlagert den Fokus der Testthemen und gibt uns die Gewissheit, dass wir das testen, was wir testen sollten - das Verhalten.
Wenn Sie TDD verwenden, wird Ihnen der Einstieg in BDD leicht fallen - es handelt sich im Grunde um eine Reihe von Best Practices dafür. BDD besteht aus einer Reihe einfacher Regeln, die vorgeben, wie Spezifikationen zu schreiben und was zu testen ist. Spezifikationen sind in drei Teile unterteilt: Given (Einrichten von Testbedingungen), When (Aufrufen von Aktionen am Subjekt) und Then (Assertions). Tests sollten beschreibende Namen haben, und bestehende Test-Frameworks ermöglichen die Verwendung von Methoden und Aussagen, die der natürlichen Sprache ähneln - all das zusammen ergibt Tests, die sowohl für technische als auch für nicht-technische Benutzer lesbar sind. Gute Namenskonventionen erweisen sich bei Regressionstests als nützlich.
BDD beinhaltet auch eine Reihe von Richtlinien für Testpersonen. Im Gegensatz zu TDD verlagert es den Schwerpunkt vom Testen der Implementierung auf das Testen des Verhaltens - und das führt zu einem besseren Design und bietet mehr Flexibilität, wenn Änderungen eingeführt werden müssen. Specs sollten wie schriftliche und ausführbare Kundenanforderungen sein - die High-Levels sollten als Akzeptanztests fungieren. Das Ziel ist es, die Tests so zu schreiben, dass sie nur dann geändert werden müssen, wenn sich die Anforderungen ändern. Die Verwendung von BDD gibt uns die Gewissheit, dass wir das testen, was wirklich abgedeckt werden muss, und es ist ein pragmatischerer Ansatz als TDD.
Wenn Sie BDD in Aktion sehen wollen, empfehlen wir Ruby. Es ist eine leistungsstarke und unterhaltsame Sprache und verfügt über ein hervorragendes BDD-Toolset.
Gurke
Cucumber ist das beliebteste Framework für BDD in Ruby. Es führt eine spezielle Sprache, Gherkin, ein, in der Sie Ihre Tests schreiben werden. Im Gegensatz zu RSpec sind die in Gherkin beschriebenen Funktionen reiner Text, nicht Codeund kann - und sollte - von jedem verstanden werden, vor allem vom Kunden.
Cucumber-Funktion sieht so aus (Beispiel aus dem Cucumber-Wiki):
Merkmal: Kurzer, aber anschaulicher Text über das, was gewünscht wird
Textuelle Beschreibung des geschäftlichen Nutzens dieser Funktion
Geschäftsregeln, die den Umfang der Funktion bestimmen
Alle zusätzlichen Informationen, die das Verständnis der Funktion erleichtern
Szenario: Eine bestimmbare Geschäftssituation
Gegeben eine Vorbedingung
Und eine andere Vorbedingung
Bei einer bestimmten Handlung des Akteurs
Und eine andere Handlung
Und noch eine weitere Handlung
Dann wird ein prüfbares Ergebnis erzielt
Und etwas anderes, das wir überprüfen können, passiert auch
Ein Szenario: Eine andere Situation
...
Die Funktionen werden später im Detail beschrieben.
Verwendung der Gurke in Ruby on Rails
Einrichtung
Der erste Schritt zur Verwendung der Gurke in Ihrem Projekt installiert wird. Fügen Sie einfach diese beiden Gems zu Ihrem Gemfile hinzu:
group :test do
gem 'cucumber-rails', :require => false
gem 'datenbank_cleaner'
end
Bündeln Sie sie, indem Sie Bündelinstallationund erzeugen Sie Cucumber-Skripte und -Verzeichnisse mit dem folgenden Befehl:
Schienen erzeugen cucumber:install
Dadurch werden config/cucumber.yml, Skript/Gurke und Eigenschaften/Verzeichnisdie Folgendes enthalten wird .feature Dateien, sowie Schrittdefinitionen und unterstützende Dateien. Um Ihre Funktionen auszuführen, verwenden Sie einen neuen Rake-Befehl:
Salatgurke
Eigenschaften
Schauen wir uns die Funktionen genauer an. Ein Feature ist etwas, das Ihre Anwendung hat oder tut - zum Beispiel sendet sie regelmäßig Newsletter oder ermöglicht es Benutzern, ihre Fotos öffentlich zu teilen. Eine Funktion besteht aus mehreren Szenarien, die beschreiben, wie diese Funktion in verschiedenen Kontexten funktioniert.
Um die grundlegende Verwendung von Cucumber in Rails zu demonstrieren, werden wir ein Feature von Grund auf schreiben. Dieses Beispiel-Feature wird das erste sein, das wir in der Anwendung schreiben werden, die im kommenden zweiten Teil dieses Artikels gezeigt wird. Diese Anwendung wird es dem Benutzer ermöglichen, Artikel und Shops zu erstellen (Shops verkaufen Artikel) und dann Einkaufslisten zu erstellen.
In der einfachsten Version zeigt die Anwendung nach der Zusammenstellung der Einkaufsliste an, in welchen Geschäften die vom Benutzer gewünschten Artikel am günstigsten sind.
Erstellen Sie zunächst eine neue Datei mit dem Namen create_item.feature im Merkmale/ Verzeichnis. Am Anfang eines .feature Datei gibt es eine Merkmal Schlüsselwort, gefolgt von einer kurzen Beschreibung des Begriffs. Zum Beispiel:
Merkmal: Artikel erstellen
In den folgenden Zeilen können Sie ein Geschäftsziel schreiben, das diese Funktion implementiert. Da Cucumber vor dem ersten Szenario geschriebenen Text ignoriert, ist es nicht notwendig, etwas zu schreiben, aber es ist definitiv eine gute Idee.
Um auf einfache Weise Einkaufslisten mit Artikeln zu erstellen, die in Geschäften in der Nähe verkauft werden
Als Benutzer
Ich möchte dem System Artikel hinzufügen
In dem Ausschnitt oben sehen Sie ein recht beliebtes Muster, mit dem Sie Geschäftsziele beschreiben können. Es besteht aus drei Teilen: Warum ist die Funktion notwendig, wer will sie, und was ist sie. Natürlich müssen Sie sich nicht an dieses Format halten, aber achten Sie darauf, dass Sie in Ihrer Beschreibung Antworten auf diese drei Fragen geben.
Szenarien
Als nächstes schreiben wir einige Szenarien. Jedes Szenario beginnt mit dem Schlüsselwort "Scenario" und enthält mehrere Schritte.
Szenario: Erstellung eines einzigartigen Artikels
Angenommen, es gibt einen Artikel "Milch".
Wenn ich auf die Hauptseite gehe
Und ich erstelle den Artikel "Brot".
Dann sehe ich "Brot" in der Artikelliste
Wenn also jemand einen Artikel mit dem Namen Milch erstellt hat, kann er auch Brot erstellen, was dazu führt, dass Brot in der Artikelliste erscheint. Wir sollten nicht auf die Erstellung eines Datensatzes in der Datenbank testen, da diese Tatsache für den Kunden keinen wirklichen Wert hat.
In den Schritten des Szenarios werden drei Hauptschlüsselwörter verwendet:
Gegebenfür die Bereitstellung von Kontext für das Szenario
Wennzur Beschreibung von Aktionen
Dannzur Beschreibung der Ergebnisse
Es ist wichtig zu beachten, dass Cucumber das Schlüsselwort step, mit dem es beginnt, ignoriert und nur den späteren Teil abgleicht. Sie können also Ihre Schritte mit "And" beginnen, wo immer es sich natürlich anfühlt. Die einzige Regel für die Wahl des richtigen Schlüsselworts ist, dass das Szenario leicht verständlich sein muss.
Definitionen der Schritte
Die Ausführung von Cucumber erzeugt nun diese Ausgabe:
[...]
Merkmal: Artikel erstellen
Zur einfachen Erstellung von Einkaufslisten mit Artikeln, die in Geschäften in der Nähe verkauft werden
Als Benutzer
Ich möchte dem System Artikel hinzufügen
Szenario: Erstellung eines einzigartigen Artikels # features/create_item.feature:6
Angenommen es gibt einen Artikel "Milch" # features/create_item.feature:7
Undefinierter Schritt: "es gibt ein "Milk"-Element" (Cucumber::Undefined)
[...]
Das liegt daran, dass Cucumber nicht weiß, was wir meinen, wenn wir sagen "es gibt ein Milk Item". Um Ihren Schritten eine Bedeutung zu geben, müssen Sie sie in Schritt_Definitionen Verzeichnis.
Es empfiehlt sich, Ihre Schrittdefinitionen nach Domänen zu gliedern. Die meisten Schritte, die wir erstellt haben, gehören zum Beispiel zum Aufgabenbereich. Daher sollten wir eine Datei mit dem Namen step_definitions/item_steps.rb und fügen Sie dort den folgenden Code ein:
Given "there is a "$name" Item" do |name|
Fabricate :item, name: name
end
Wenn "Ich erstelle "$name" Gegenstand" do |name|
innerhalb "#new_item" do
fülle "Name", mit: Name
klick_auf "Erstellen"
end
end
Then "Ich sehe "$name" in der Artikelliste" do |name|
innerhalb von ".items" do
expect(page).to have_content name
end
end
Die Schrittdefinitionen basieren in der Regel auf Capybara. Wenn Sie mit Capybara nicht vertraut sind, sollten Sie sich die Links am Ende dieses Artikels ansehen.
Es gibt noch einen weiteren Schritt, der definiert werden muss und nicht wirklich in die Einzelschritte passt. Man könnte ihn unterbringen in main_page_steps.rb:
Wenn "Ich gehe auf die Hauptseite" do
visit root_path
end
Schlussfolgerung
Dies ist eine sehr einfache Geschichte für eine sehr einfache Funktion. Ihr Zweck war es, Kernkonzepte von BDD zu demonstrieren, wie sie in Cucumber verwendet werden. Das Schreiben guter Stories erfordert jedoch etwas mehr. Als Entwickler müssen Sie Ihre Denkweise komplett ändern - vergessen Sie die Implementierung und konzentrieren Sie sich stattdessen auf die Geschäftsziele. Cucumber erleichtert diesen Übergang durch die clevere Verwendung von einfachen Textstories.