Kolumne: Req4Arcs

Ausführbare Spezifikationen (und eine Portion BDD)

Peter Hruschka, Gernot Starke

© S&S_Media

In einer der letzten Folgen haben wir bereits über beispielhafte Spezifikationen geschrieben. Diesmal möchten wir konkreter auf die Möglichkeiten der Ausführbarkeit solcher Spezifikationen eingehen. Dazu werden wir einen Ausflug in die großartigen Möglichkeiten von Behavior-driven Development unternehmen.

Diesen Begriff hat Dan North schon 2006 geprägt, als Reaktion auf immer wiederkehrende Probleme mit Test-driven Development. Sein einfacher, aber genialer Vorschlag zur Verbesserung von TDD lautete: „Die Namen von Testmethoden sollten umgangssprachliche Sätze sein“. In Kurzform: BDD versucht, Test-driven Development, einige Aspekte von Domain-driven Design sowie Techniken des automatisierten Akzeptanztests miteinander zu verbinden, um Entwicklungsteams, Fachleute und andere Stakeholder mit einer gemeinsamen Sprache auszustatten.

Klingt erstmal wie reinstes Marketingdeutsch – enthält aber viel Wahrheit. Unsere Recherchen zum aktuellen Stand von BDD und den zugehörigen Tools haben bei uns einen sehr positiven Eindruck hinterlassen.

In BDD geht’s um Spezifikation

Fangen wir einmal vorne an. Wir wollen doch alle (Entwicklungsteams inklusive ArchitektInnen, Product Owner, Requirements Engineers, Tester und andere) zuerst einmal verstehen, was unser System denn genau tun soll. Natürlich iterativ und in kleinen Portionen, weil sich viele Dinge und Erkenntnisse erst während der Entwicklung ergeben. Dieses „Was-das-System-genau-tun-soll“ bildet den Kern von BDD. Es geht um das Verhalten des Systems, um das genaue Verständnis, was die wesentlichen Stakeholder denn von dem System erwarten und warum. Es geht nicht(!) primär um automatisch ausführbare Testfälle, sondern eben erstmal um ein angemessen präzises Verständnis von Anforderungen – was auch der Grund ist, weswegen wir das Thema in dieser Kolumne aufgreifen.

BDD arbeitet Top-Down

Ähnlich wie wir das zu Beginn unserer Req4Arcs-Kolumne vorgeschlagen haben, fordert auch BDD, bei der Spezifikation mit einer strategischen Zielsetzung (auch Vision genannt) zu beginnen, damit wir als Entwicklungsteam wissen, wohin die Reise insgesamt führen soll [1]. Anschließend brechen wir beim BDD diese Anforderungen auf sogenannte Features herunter, die wir dann wiederum durch Beispiele konkretisieren. Erst diese Beispiele versuchen wir dann bei Bedarf zu automatisieren. John Ferguson Smart [2] hat dafür eine sehr feingranulare Hierarchie vorgeschlagen, die Sie (auszugsweise)in Abbildung 1 finden.

Abb. 1: Hierarchie von Anforderungen in BDD (nach [2])

Abb. 1: Hierarchie von Anforderungen in BDD (nach [2])

Abb. 2: Beispiel für Impact-Map nach [2]

Abb. 2: Beispiel für Impact-Map nach [2]

 

An dieser Stelle interessieren uns die eher konkreten Teile dieser Pyramide beginnend bei den sogenannten Features. Die zu finden, stellt manchmal schon eine ordentliche Herausforderung dar, bei deren Überwindung uns unter anderem die Methode Impact Mapping (Kasten: „Impact Map“) helfen kann. Außerdem haben wir in den zurückliegenden Folgen mehrmals über funktionale Anforderungen geschrieben – auch da werden Sie fündig. Gehen wir also hier optimistisch davon aus, dass Sie mit Ihrer Lieblingsmethodik vernünftige und zum Gesamtziel beitragende Features finden. Die priorisieren Sie natürlich anhand der bekannten Geschäftsziele – aber das kennen Sie als treue LeserIn unserer Kolumne ja bereits. Die offene Frage lautet: „Wie können wir die jetzt ausführbar machen?“

Impact Map – von Zielen zu Features

Gojko Adzic hat 2012 unter dem Namen Impact Mapping eine Methode vorgestellt, um die Beziehung zwischen den einem System zugrunde liegenden Unternehmenszielen, den betroffenen Akteuren und den Features, mit deren Hilfe das System die erwarteten Ergebnisse liefern kann, zu visualisieren. Impact Maps sind einfach zu erstellen und leicht zu verstehen und können ein sehr nützliches Werkzeug zur Dokumentation solcher Unternehmensziele und der Validierung von Annahmen sein. Das macht Impact Maps zu einem kreativen Werkzeug, auf das wir in einer zukünftigen Folge dieser Kolumne noch etwas genauer eingehen werden. Hier schon mal ein kleiner Ausblick und ein Beispiel:

Eine Impact Map ist eine Art Mindmap, die während der Konversation verschiedener Stakeholder (u. a. Manager, Fachexperten und Entwicklungsteam) erstellt wird. Das Gespräch dreht sich um vier Arten von Fragen:

  • Warum? Was ist das zugrunde liegende Unternehmensziel, das wir erreichen wollen?
  • Wer ist betroffen als User oder sonstiger Stakeholder?
  • Wie können Stakeholder zu dem Ziel beitragen? (Dieses „Wie“ ist der Impact, der Namensgeber der Methode. In der Pyramide aus Abbildung 1 sind das die Capabilities, die Fähigkeiten unseres Systems.)
  • Was kann das System tun? (Die „Was“-Antworten sind oftmals gute Kandidaten für unsere Features, die wir dann ja letztlich automatisieren wollen – sowohl als ausführbare Spezifikation wie auch natürlich als Teile unseres Systems.)

Das Beispiel aus Abbildung 2 stammt aus [2] und illustriert aus unserer Sicht diese Ansätze ganz gut.

Konkretisierung nach Schema F

Unsere Features werden oftmals noch als relativ abstrakte Wünsche oder Zielvorstellungen ausgedrückt, insbesondere ohne Implementierungsdetails. Diese fügen wir in den Verfeinerungen (üblicherweise Stories oder Szenarien genannt) hinzu, dann jeweils mit klar formulierten Akzeptanzkriterien. Letzteres klingt schon ein wenig nach Automatisierung, besonders wenn wir den BDD-Vorschlägen folgen und unsere Stories oder Beispiele gemäß der einfachen Syntax der Sprache Gherkin (Kasten: „Gherkin kompakt“) formulieren. Gherkin-Szenarien bestehen aus dem Dreisatz Given-When-Then. Ein Beispiel inklusive dem dazugehörigen Feature finden Sie in Listing 1.

Feature: Team Scoring
  Teams starts with zero score
  Correct answer gets points depending on how difficult it is
Scenario: Score starts at zero
  Given I register a team 
  Then my score is zero
Scenario: Correct easy answer scores 10
  Given I register a team
  When I submit a correct easy answer
  Then my score is 10
Scenario: Correct hard answer scores 50
  Given I register a team
  When I submit a correct hard answer
  Then my score is 50

Die Syntax der Sprache Gherkin (englisch für Essiggurke) wird von einigen Werkzeugen der Cucumber-Familie [7] (englisch für Gurke) implementiert. Was „Gurken“ mit Anforderungen oder Akzeptanztests zu tun haben, ist eine nette (private) Geschichte, des ursprünglichen Entwicklers Aslak Hellesøy – Sie können sie auf Quara selbst einmal nachlesen.

Interessant ist noch, dass die Schlüsselworte der Sprache Gherkin neben dem ursprünglichen Englisch in viele (>50) andere natürliche Sprachen übersetzt worden sind, damit Fachleute überall auf der Welt in ihrer eigenen Sprache Features und Szenarien mit BDD konkretisieren können. Hier im Artikel bleiben wir aber mal bei Englisch.

Gherkin kompakt

Gherkin bezeichnet die DSL diverser BDD-Tools und verfolgt zwei Ziele: einerseits eine hohe Verständlichkeit für Businessstakeholder und andere Nicht-ITler, andererseits eine einfache Automatisierbarkeit mit BDD-Tools. Gherkin bildet damit eine gemeinsame Sprache für sowohl Anforderungen als auch automatisierte Tests.

Gherkin bezeichnet die DSL diverser BDD-Tools und verfolgt zwei Ziele: einerseits eine hohe Verständlichkeit für Businessstakeholder und andere Nicht-ITler, andererseits eine einfache Automatisierbarkeit mit BDD-Tools. Gherkin bildet damit eine gemeinsame Sprache für sowohl Anforderungen als auch automatisierte Tests.

In Gherkin schreiben Sie Anforderungen in natürlicher Sprache und folgen dabei einer spezifischen Struktur. Jedes Szenario besteht aus einer Folge von Schritten (Steps), die jeweils mit einem der Schlüsselworte Given, When, Then, And oder But beginnen. Ja, das geht auch auf Deutsch, obwohl wir hier im Artikel Englisch verwenden. Die Reihenfolge ist immer Given-When-Then:

  • Given (gegeben sei, angenommen): Vorbedingung, bestimmte Situation oder Sachverhalt
  • When (wenn): ein bestimmtes Ereignis, das eintritt, oder eine Aktion, die stattfindet
  • Then (dann): das erwartete Ergebnis
  • And (und) und But (aber) können Sie verwenden, um jeden der drei Teile etwas lesbarer zu formulieren

Mehrere ähnliche Szenarien können Sie mit Hilfe von Tabellen deutlich kompakter schreiben (Spock Framework nennt das Data-driven), beispielsweise:

Scenario Outline: Earning interest
  Given I have an account of type  with a balance of 
  When the monthly interest is calculated
  Then I should have earned at an annual interest rate of  
  And I should have a new balance of 

Ihr freundliches BDD-Framework (etwa Cucumber) würde das Szenario für jede Zeile der Tabelle einmal ausführen und die Werte der Variablen in ersetzen. Bleibt noch zu sagen, dass es für viele IDEs (IntelliJ, Eclipse, Atom, VS Code) mittlerweile sehr guten Gherkin-Support gibt.

Vom Szenario zur Ausführung

Zur Ausführung unserer Szenarien setzen wir jetzt Frameworks wie Cucumber, JBehave oder Spock ein. In Abbildung 3 sehen Sie die Zusammenhänge im Überblick. Beginnen wir mit Cucumber (wobei diese Erläuterungen fast identisch auch für JBehave oder das SpecFlow-Framework im .NET-Umfeld gelten). Cucumber kann unser Team-Scoring-Feature von oben schon ausführen, beschwert sich allerdings über „undefined steps“. Logisch, denn bislang fehlt unseren Given-When-Then Szenarien ja noch immer die Verbindung zum Quellcode unseres Systems.

Dazu schreiben wir für Cucumber so genannte Step-Definitions, die unsere textuellen Beschreibungen im .feature-File interpretieren. Das sieht dann wie folgt aus:

@Given("I register a team")
public void i_register_a_team() {
  // Anwendungscode...
}

In der @Given-Annotation wiederholen wir den Text aus der Given-Klausel unseres Szenarios. Diese Source steht in einer normalen Java- oder Groovy-Klasse – in der wir natürlich auch Variablen für unser Team, den Score oder andere schicke Dinge deklarieren können, respektive unseren eigentlichen Quellcode aufrufen. Sie raten jetzt richtig: Es gibt ebenfalls die Annotationen @When und @Then, die analog funktionieren.

Diese Kolumne kann und möchte lediglich einen Überblick über die Möglichkeiten ausführbarer Spezifikationen geben – für eine gründliche Einführung schauen Sie in [1] oder auf auf der cucumber.io-Webseite.

Abb. 3: Features und ausführbare Szenarien nach [1]

Abb. 3: Features und ausführbare Szenarien nach [1]

Spock und BDD

Einer von uns Autoren (Gernot) ist erklärter Fan von Spock und hat eine Menge Code Test- und/oder Specification-driven mit Hilfe dieses großartigen Werkzeugs entwickelt. In Abbildung 3 finden Sie Spock zusammen mit dem klassischen JUnit als Möglichkeit, Low-Level-Spezifikationen zu schreiben, da Spock mit Fokus auf codenahe Stakeholder entwickelt wurde und nicht wie Gherkin den Fokus auf Businessstakeholder richtet. Spock-Spezifikationen sind bezüglich des Kodieraufwands wesentlich einfacher und schlanker als Gherkin-Features mit ihren (eigenständigen respektive zusätzlichen) Step-Definitionen. Andererseits können wir uns kaum Businessstakeholder vorstellen, die (freiwillig) Spock-Spezifikationen lesen und schreiben würden, denn sie lesen sich ähnlich codelastig wie die Step-Definitionen von Cucumber.

Falls Sie als Entwickler jedoch spezifizieren möchten, dass in einer bestimmten Situation eine Exception eines bestimmten Typs geworfen wird (oder auch nicht), dann ist Spock bestimmt die eleganteste und einfachste Art, das zu tun. Daher nimmt Spock in der von Gherkin dominierten BDD-Welt eine wichtige Rolle ein – und wir empfehlen es besonders für JVM-basierte Systeme wärmstens.

Ausblick

Es geht, wie so oft, noch einen kleinen Schritt weiter. Die ausgeführten Spezifikationen werden durch JUnit-ähnliche Runner ausgeführt – und von denen können wir einen Report generieren lassen: Diesen Ansatz finden wir als Living Documentation etwa in Serenity frei verfügbar umgesetzt. Die Ergebnisse haben uns stark beeindruckt und können bestimmt auch Ihnen in ihrer (schweren!) täglichen Architektur- und Entwicklungsarbeit helfen!

Fazit

Behavior-driven Development ist für unsere Architektenrolle wirklich interessant und gewinnbringend: Brechen Sie (mit Hilfe Ihrer Stakeholder) funktionale Anforderungen auf Fähigkeiten und Features herunter und diese dann auf Szenarien (aka Stories), wobei Sie von den (High-Level-)Geschäftszielen ausgehen. Mit ein wenig zusätzlichem Glue Code (in der JVM-Welt: Cucumber/Gherkin, JBehave oder Spock) bekommen Sie auf diese Weise ausführbare Spezifikationen mit ordentlichen Akzeptanzkriterien. Die Krönung: „Lebendige Dokumentation“, die sich mit jeder Ausführung Ihrer Spezifikationen neu generiert, ist ein garantiert aktueller Überblick darüber, welche Features gerade funktionieren und wo es Probleme gibt.

Wer die letzten Folgen unserer Kolumne gelesen hat, wird direkt an manche noch fehlenden Qualitätsanforderungen denken, aber mit Hilfe der ausführbaren Spezifikationen gemäß BDD können wir schon mal einen ganz ordentlichen Teil von Anforderungen erfassen und kontinuierlich testen. Insofern können Sie loslegen, ein paar Szenarien für Ihr aktuelles System schreiben und von einem der BDD-Tools mal ausführen lassen. In diesem Sinne: Bis zur nächsten Folge, und möge die Macht ausführbarer Specs mit Ihnen sein!

Geschrieben von
Peter Hruschka
Peter Hruschka
Informatikstudium an der TU Wien, Promotion über Echtzeit-Programmiersprachen. 18 Jahre im Rahmen eines großen deutschen Softwarehauses verantwortlich für Software-Engineering. Initiator, Programmierer und weltweiter Prediger und Vermarkter eines der ersten Modellierungstools. Seit 1994 selbstständig als Trainer und Berater mit den Schwerpunkten Software-/Systemarchitekturen und Requirements Engineering, bevorzugt im technischen Umfeld.
Gernot Starke
Gernot Starke
    Informatikstudium an der RWTH Aachen, Dissertation über Software-Engineering an der J. Kepler Universität Linz. Langjährige Tätigkeit bei mehreren Software- und Beratungsunternehmen als Softwareentwickler, -architekt und technischer Projektleiter. 1996 Mitgründer und technischer Direktor des „Object Reality Center“, einer Kooperation mit Sun Microsystems. Dort Entwickler und technischer Leiter des ersten offizielle Java-Projekts von Sun in Deutschland. Seit 2011 Fellow der innoQ GmbH.  
Kommentare

Hinterlasse einen Kommentar

Hinterlasse den ersten Kommentar!

avatar
4000
  Subscribe  
Benachrichtige mich zu: