Um im Vorfeld möglichst viele Fehler bei der Softwareentwicklung zu vermeiden und eine hohe Qualität zu gewährleisten, ist Softwaretesting unerlässlich. Es werden alle Funktionen und Möglichkeiten der Nutzung überprüft, um bisher unentdeckte Programmierfehler, Probleme oder Fehlfunktionen ausfindig zu machen. Softwaretests können auf verschiedenen Ebenen stattfinden – von Unit-Tests einzelner Methoden bis hin zu Akzeptanztests, bei denen die funktionalen Erwartungen und Anforderungen im Gebrauch getestet werden. Dadurch kann die Funktionsweise der Software relativ leicht verständlich dokumentiert und z. B. den Stakeholdern präsentiert werden. Die Verbesserung der Kommunikation zwischen Entwicklerteam und Stakeholdern, die die Zusammenarbeit erleichtert, ist einer der Grundgedanken des Behavior-Driven-Development.
Behavior-Driven-Development (BDD)
BDD beschreibt eine verhaltensgetriebene Arbeitsweise, die die Zusammenarbeit über verschiedene Rollen hinweg verbessern kann. Häufig liest man im Zusammenhang mit BDD auch den Begriff TDD (Test-Driven-Development) - eine testgetriebene Arbeitsweise, bei der vor der Implementierung der Software die passenden Tests zum Feature geschrieben werden - auf die wir im Folgenden aber nicht näher eingehen werden.
Zum 20. Geburtstag des Agilen Manifests ist eine wichtige Botschaft inzwischen bei den meisten IT-Unternehmen angekommen: Software wird für den Kunden entwickelt, soll einen Mehrwert für ihn haben und laufend anhand von Feedback verbessert werden. Die langen Phasen der technischen Analyse sollen durch kurze Entwicklungszyklen ersetzt werden, um schnell Feedback einholen zu können und flexibel auf Änderungen in den Anforderungen reagieren zu können. Funktionsfähige Software hat Vorrang vor ausführlicher Dokumentation. Im Zuge dessen werden die gestellten Softwareanforderungen nicht mehr mit mehrseitigen, technisch ausgeprägten Anforderungsdokumenten beschrieben, sondern in Form von User-Stories. Details der Anforderung werden durch Beispiele übermittelt, die aus der Sicht des Nutzers, zum großen Teil in Alltagssprache, formuliert werden. Dies erleichtert es allen beteiligten Rollen, das gewünschte Verhalten der Software zu verstehen, den Mehrwert für die Nutzer stärker hervorzuheben und die Absichten hinter den Anforderungen zu klären. Das Ziel und der Nutzen der Software stehen hier im Vordergrund; die genaue technische Umsetzung wird meistens dem Entwicklungsteam überlassen.
Für genau diese Methode der Anforderungsanalyse wurde BDD entwickelt. Die Technik unterstützt die agile Softwareentwicklung und stärkt die Zusammenarbeit zwischen Kunden und Entwicklungsteam. BDD hat die folgenden drei Kernprinzipien:
- Verstärke die Zusammenarbeit zwischen verschiedenen Rollen, sodass ein gemeinsames Verständnis des zu lösenden Problems erzeugt wird.
- Arbeite in schnellen, kurzen Iterationen, um Feedbackzyklen zu verkürzen.
- Erzeuge eine Systemdokumentation, die automatisch gegen das Verhalten des Systems getestet wird.
Durch das Zusammenarbeiten verschiedener Rollen (z. B. Softwareentwickler, Product-Owner, Designer) und das stärkere Einbeziehen der Stakeholder sollen schon vor der abgeschlossenen Implementierung bestmöglich die Anforderungen verstanden und laufend neu gewonnene Erkenntnisse geteilt werden. Dazu müssen laufend die Erwartungen und die aktuelle Version der Software miteinander verglichen und aufeinander abgestimmt werden. Dazu kann man sich zum Beispiel an folgenden Ablauf halten:
- Sprich über eine neue User-Story anhand von konkreten Beispielen des Verhaltens. Einige dich auf Details, die erwartet werden.
- Dokumentiere die Beispiele so, dass ihre Einhaltung automatisiert überprüft werden kann.
- Implementiere das beschriebene Verhalten und unterstütze die Entwicklung durch automatisierte Tests.
Eines der bekanntesten Tools, um einen nach BDD-orientierten Arbeitsablauf zu unterstützen, ist das Framework Cucumber.
Cucumber
Das Framework besteht aus zwei Schichten. Die erste Schicht besteht aus Feature-Files, in denen die Funktionalität des Systems beschrieben wird. Mit Hilfe von konkreten Beispielen wird das Verhalten der Software dokumentiert. Dabei wird die deskriptive Sprache Gherkin verwendet, die der Beschreibung mithilfe von Keywords eine Struktur verleiht. Die Testfälle haben folgende Form:
Feature: Blogartikel anzeigen
Szenario: Ich will den Blogartikel ‘BDD & Cucumber‘ lesen
Angenommen ich bin auf der cronn-Webseite
Wenn ich auf den Tab ‘Blog’ klicke
Und ich den Artikel ‘BDD & Cucumber' auswähle
Dann wird dieser Artikel angezeigt
Bis auf die Keywords kann jede Formulierung gewählt werden, sodass es einfach ist, ein gemeinsames Verständnis der Funktionalität der Software zu erreichen. Gleichzeitig dienen diese Testfallbeschreibungen selbst als lebendige Dokumentation der Software. So wird der Funktionsumfang verständlich beschrieben und Abweichungen vom erwarteten Verhalten schnell bemerkt. In dieser Kombination von Testfallausführung und Dokumentation liegt die Stärke des Cucumber-Frameworks im Vergleich zu anderen Testframeworks.
Um die in den Feature-Files beschriebenen Schritte eines Testfalls auszuführen, benötigt Cucumber den sogenannten “Glue-Code”. In einer Programmiersprache der Wahl wird die Funktionalität hinter den einzelnen Schritten implementiert ( Java und Ruby sind am weitesten verbreitet und am besten unterstützt). Durch die freie Kopplung an eine beliebige Programmiersprache sind den Möglichkeiten des Testens (fast) keine Grenzen gesetzt und man ist nicht durch die Features eines Testtools eingeschränkt. Natürlich ist dadurch die Hürde, Cucumber als Testframework zu benutzen, ein wenig höher, da für die Implementierung des “Glue-Codes” ein Grundverständnis der ausgewählten Programmiersprache erforderlich ist.
Cucumber unterstützt durch die Trennung von Testfallbeschreibung und -implementierung die Grundsätze des Behaviour-Driven-Development. Durch die zugängliche und leicht verständliche Beschreibung der Testfälle wird das gemeinsame Verständnis der Funktionsweise der Software erleichtert. Dies bildet die Grundlage für einen Austausch zwischen allen involvierten Rollen. Durch die Beschreibung konkreter Beispiele in natürlicher Sprache können viele Unklarheiten bereits vor der Implementierung erkannt und geklärt werden. Auch der Umfang des Feature-Files kann ein Indikator für die Komplexität der dazugehörigen User-Story sein. Da die Testfälle sowohl Dokumentation als auch Testdurchführung beinhalten, sind der aktuelle Stand und die Funktionsweise der Software jederzeit sichtbar und die automatisierten Tests stellen damit einen aussagekräftigen Teil der Qualitätssicherung dar.
Falls du das einfach mal ausprobieren möchtest, schau dir den Blogartikel Cucumber mit jUnit 5 an. Dort erklärt Sebastian, wie man schnell sein eigenes Cucumber-Projekt mit Java aufsetzt.