Behavior Driven Development und seine Umsetzung mit Cucumber

Foto des Autors
Ahmad Aljeld Zubaydi

Tauchen wir gemeinsam in die Welt des Behavior Driven Development ein. Lass uns entdecken, wie diese Methode die Art und Weise der Software-Entwicklung revolutioniert.

Titelbild zum Beitrag "Behavior Driven Development und seine Umsetzung mit Cucumber"

Software-Testing zielt darauf ab, fehlerfreie Produkte an den Start zu bringen. Ein frühzeitiges Testen von Software kann Geld und Zeit sparen, denn die teuersten Fehler sind jene, die erst nach dem Produktrelease erkannt werden. Im Folgenden möchte ich erläutern, wie Behavior Driven Development als eine Disziplin des Software-Testings dabei helfen kann, ein erfolgreiches Produkt an den Start zu bringen.

Mein Name ist Ahmad Aljeld Zubaydi und ich arbeite seit zwei Jahren als IT-Berater bei Conciso. Bei großen Projekten wie dem Vendo-Projekt der Deutschen Bahn habe ich bereits einige Erfahrungen sammeln können. Ich freue mich darauf, diese Erkenntnisse mit dir zu teilen. Tauchen wir gemeinsam in die Welt des Behavior Driven Development ein. Lass uns entdecken, wie diese Methode die Art und Weise der Software-Entwicklung revolutioniert.

Was ist Behavior Driven Development?

Die Grundlagen der Software-Entwicklung haben sich in den vergangenen Jahren verändert. In einer Welt, die sich ständig weiterentwickelt, wird die Fähigkeit, Produkte effizient und bedarfsgerecht zu entwickeln, zunehmend zur Herausforderung. Hier kommt Behavior Driven Development (BDD) ins Spiel – eine innovative Methode, die nicht nur die Entwicklungsprozesse optimiert, sondern auch eine nahtlose Zusammenarbeit zwischen Entwickler:innen, Tester:innen und der Fachseite ermöglicht. Behavior Driven Development ist nicht nur ein Schlagwort, sondern der Schlüssel zu einem erfolgreichen Produktstart. Durch meine Erfahrung bei Conciso habe ich erlebt, wie BDD transformative Ergebnisse erzielen kann.

Das gelingt aufgrund folgender Aspekte:

  • Behavior Driven Development ist, wie bereits erwähnt, ein Ansatz in der Software-Entwicklung, der auf eine effektive Zusammenarbeit zwischen Entwickler:innen, Tester:innen und der Fachseite abzielt. Der Fokus liegt bei diesem Ansatz auf der Definition des Anwendungsverhaltens in leicht verständlichem Text, den Anforderungen, den Testfällen und darüber hinaus auf dem erwarteten Verhalten der Anwendung.
  • Die klare Definition der Fachbegriffe in Bezug auf die Software-Entwicklung ist ein wichtiger Aspekt im Behavior Driven Development. Die Verwendung der Kund:innensprache bei Testformulierungen erleichtert es allen am Entwicklungsprozess Beteiligten, diese Testformulierungen ohne Schwierigkeiten nachvollziehen zu können. Ferner erleichtert es Kommunikation und Zusammenarbeit.
  • Bei der Behavior Driven Development-Methodik fokussieren wir uns auf den Test-First-Ansatz: Wir erstellen zuerst die Testfälle, bevor wir mit dem Schreiben des eigentlichen Codes beginnen. Auf diese Weise stellen wir ein gemeinsames Verständnis für die geschäftlichen Anforderungen sicher, sodass die Implementierung exakt den festgelegten Anforderungen entspricht.
  • Tools wie Cucumber, JBehave oder SpecFlow unterstützen die Umsetzung von Behavior Driven Development. Insbesondere in der Entwicklung von Anwendungen mit komplexen Anforderungen und einer Vielzahl von Beteiligten erweist sich Behavior Driven Development als äußerst nützlich. Diese methodische Herangehensweise fördert nicht nur die Transparenz und Verständlichkeit der Anforderungen. Sie erleichtert sowohl die Kommunikation und Koordination innerhalb des Entwicklungsteams als auch mit den relevanten Interessengruppen.

Die 3 Hauptregeln des Behavior Driven Developments

  1. Auf das Notwendige konzentrieren: Die erste Regel betont die Wichtigkeit, sich auf das Wesentliche zu fokussieren, effizient zu analysieren und zu planen, um Zeit nicht unnötig zu verschwenden.
  2. Den Stakeholder:innen Wert liefern: Die Ausrichtung auf Stakeholder:innen, die ein Interesse an geschäftlichem Mehrwert haben, stehen im Mittelpunkt der zweiten Regel. Diese besagt, dass sämtliche Aktivitäten im Projekt darauf abzielen müssen, einen solchen Nutzen zu generieren.
  3. Fokus auf das Verhalten: Diese Regel fordert, dass alle Projektbeteiligten das Anwendungsverhalten in einer allgegenwärtigen Sprache beschreiben können, um die Kommunikationskluft zwischen technischen und nicht-technischen Personen zu überbrücken.

Behavior Driven Development und Agilität

Obwohl Behavior Driven Development grundsätzlich auch in klassischen Projekten eingesetzt werden kann, entfaltet es seine wahre Stärke besonders in der Kombination mit agilen Methoden.

Der Zweck von Behavior Driven Development besteht darin, Tests für Kund:innen und Stakeholder:innen verständlicher zu gestalten. Ferner sollen die Prinzipien der agilen Software-Entwicklung unterstützt und vorangetrieben werden. Dieser Zusammenhang lässt sich durch die folgenden Punkte verdeutlichen:

  1. Kund:innenzentriertes Denken: Dies ist entscheidend in der Agilität. Behavior Driven Development fördert diese Ausrichtung, indem es Entwickler:innen, Tester:innen und nicht-technische Stakeholder:innen dazu ermutigt, klare und verständliche Verhaltensspezifikationen gemeinsam zu erstellen. Dadurch entsteht eine effektive Zusammenarbeit, in der alle Beteiligten die Anforderungen verstehen und genehmigen können.
  2. Inkrementelle Entwicklung: Inkrementelle Entwicklung steht im Fokus agiler Methoden, die Software in kurzen Iterationen liefern. Behavior Driven Development ermöglicht dies, indem es erlaubt, Verhaltensspezifikationen schrittweise zu entwickeln und die Software in kleinen Schritten zu gestalten, wobei die Spezifikationen als Referenz dienen.
  3. Automatisierung von Tests: In agilen Projekten spielen automatisierte Tests eine entscheidende Rolle, um sicherzustellen, dass die Software kontinuierlich überprüft wird. Dank Behavior Driven Development ist es möglich, Tests automatisch anhand der erstellten Verhaltensspezifikationen durchzuführen.Diese Automatisierung ermöglicht es Entwicklungsteams effizient sicherzustellen, dass die Software den Anforderungen entspricht. Es minimiert menschliche Fehler, gewährleistet die Wiederholbarkeit der Tests und fördert eine agile und reaktionsfähige Entwicklungsumgebung.
  4. Feedback-Schleifen: Agilität fördert schnelles Feedback von Kund:innen und Teammitgliedern. Behavior Driven Development unterstützt dieses Prinzip, indem es sicherstellt, dass Tests frühzeitig und kontinuierlich ausgeführt werden. Dadurch können Probleme frühzeitig erkannt und behoben werden.
  5. Kontinuierliche Verbesserung: In agilen Ansätzen geht es darum, sich ständig zu verbessern und sich an veränderte Anforderungen anzupassen. Mit Behavior Driven Development können Teams ihre Verhaltensspezifikationen anpassen, um Änderungen in den Anforderungen widerzuspiegeln, ohne die Tests von Grund auf neu schreiben zu müssen.
Was kann passieren, wenn man Software-Testing vernachlässigt?

Mit dem Klick auf das Video ist Ihnen bewusst, dass Google einige Cookies setzen und Sie ggfs. auch tracken wird.

Das Testing-Framework Cucumber

Nachdem ich die Grundprinzipien des Behavior Driven Developments erläutert habe, möchte ich nun auf das Testing-Framework Cucumber eingehen. Die Wahl fiel aufgrund verschiedener Faktoren auf Cucumber:

  • Seine klare Syntax ermöglicht eine effektive Kommunikation zwischen technischen und nicht-technischen Teammitgliedern.
  • Im Vergleich zu anderen Tools zeichnet sich Cucumber durch eine intuitive Struktur und Flexibilität aus, da es verschiedene Programmiersprachen unterstützt.
  • Durch Cucumber lassen sich automatisierte Testszenarien in einer einfach verständlichen Sprache erstellen, die ein domänenspezifisches Vokabular verwendet.

Im Folgenden werde ich den Aufbau, die Schlüsselwörter sowie die Features von Cucumber erläutern.

Was ist Cucumber?

Cucumber ist ein Open-Source-Tool, das in der Software-Entwicklung und insbesondere im Bereich der Testautomatisierung Verwendung findet. Es wurde ursprünglich für Behavior Driven Development entwickelt, ist jedoch flexibel genug, um auch für andere Testzwecke eingesetzt zu werden.

Der Aufbau von Cucumber

Zu den Bestandteilen von Cucumber gehören Gherkin-Syntax, Feature-Dateien und Step-Definitionen.

  • Die Gherkin-Syntax setzt sich aus speziellen Schlüsselwörtern wie „Funktionalität“, „Szenario“, „Angenommen“, „Wenn“ und „Dann“ etc. zusammen. Diese Schlüsselwörter verleihen den ausführbaren Spezifikationen Struktur und Bedeutung, beschreiben den Ablauf von Tests und sind in zahlreiche gesprochene Sprachen übersetzt.
  • Eine Feature-Datei in Cucumber beschreibt die Funktionalität einer Software. Es enthält Szenarien, die die erwarteten Verhaltensweisen der Software für verschiedene Anwendungsfälle darstellt. In der Feature-Datei wird die Gherkin-Syntax verwendet.
  • Die Step-Definitionen in Cucumber sind die reine Implementierung, die mit den einzelnen Schritten eines Szenarios in einer Feature-Datei verknüpft sind. Diese Step-Definitionen können in vielen Programmiersprachen wie Java, Ruby, Python geschrieben werden. Sie enthalten den tatsächlichen Code, der ausgeführt wird, wenn ein bestimmter Schritt im Szenario erreicht wird.

In diesem Kontext wird die deutsche Sprache verwendet. Auf diese gehe ich im folgenden genauer ein:

Cucumber Schlüsselwörter

  • Funktionalität
    Das Funktionalität-Schlüsselwort dient dazu, den übergeordneten Kontext oder das Gesamtkonzept in einer Feature-Datei zu definieren, welches anschließend getestet wird. Nach dem Funktionalität-Schlüsselwort können kurze Zusammenfassungen des Features hinzugefügt werden, die zwar von Cucumber während der Laufzeit ignoriert werden, aber für ein späteres Reporting verfügbar sind. Diese Beschreibungen werden durch Szenario-Abschnitte ergänzt, die konkrete Testfälle veranschaulichen.
  • Regel
    Das optionale Regel-Schlüsselwort hat den Zweck, eine zu implementierende Geschäftsregel zu repräsentieren. Es liefert zusätzliche Informationen für ein Feature und dient dazu, mehrere Szenarien, die zu dieser Geschäftsregel gehören, zusammenzufassen. Eine Regel sollte ein oder mehrere Szenarien enthalten, die die jeweilige Regel veranschaulichen. Im Wesentlichen hilft die Regel dabei, die Lesbarkeit und Struktur von umfangreichen Feature-Dateien zu verbessern.
  • Szenario
    In Cucumber bezieht sich das Schlüsselwort Szenario auf einen abgeschlossenen Testfall, der einen spezifischen Anwendungsfall oder eine bestimmte Funktionalität repräsentiert.
    Jedes Szenario kann beliebig viele Schritte haben, aber es ist zu empfehlen 3 bis 5 Schritte pro Szenario zu definieren. Zu viele Schritte führen dazu, dass das Testszenario seine Aussagekraft als Spezifikation und Dokumentation verliert.

    Hier ist ein einfaches Beispiel für zwei Szenarien mit der Verwendung des Funktionalität– und des Regel-Schlüsselwortes:
# language: de
Funktionalität: Prüfung der Taschenrechner-Funktionen
  Regel: Grundlegende Rechenoperationen
    
    Szenario: Addition von zwei Zahlen
      Angenommen der Taschenrechner ist eingeschaltet
      Wenn ich 5 und 7 addiere
      Dann sollte das Ergebnis 12 sein
      
    Szenario: Subtraktion von zwei Zahlen
      Angenommen der Taschenrechner ist eingeschaltet
      Wenn ich 10 von 15 subtrahiere
      Dann sollte das Ergebnis 5 sein
Code-Sprache: Gherkin (gherkin)

In diesem Beispiel beschreibt das Schlüsselwort Funktionalität den Testumfang und das Schlüsselwort Regel fasst die grundlegenden Testszenarien zusammen.
Zu Beginn jedes Testszenarios ist eine kurze Beschreibung erforderlich – gefolgt von den Schritten Angenommen, Wenn und Dann, die die Voraussetzungen, die Aktionen und die erwarteten Ergebnisse für dieses spezifische Szenario festlegen.

  • Angenommen, Gegeben sei, Gegeben seien
    In Cucumber wird das Schlüsselwort Angenommen oder sein Synonym in einem Szenario genutzt, um den Ausgangszustand oder die Voraussetzungen zu definieren, unter denen das Szenario beginnen soll.
  • Wenn
    Dieses Schlüsselwort beschreibt die Aktionen, die im Szenario ausgeführt werden. 
  • Dann
    Das Schlüsselwort Dann beschreibt die erwarteten Ergebnisse oder das erwartete Verhalten nach den Aktionen.
  • Und, Aber
    Die beiden Schlüsselwörter dienen dazu, zusätzliche Schritte in einem Szenario zu beschreiben.
    Das Und-Schlüsselwort wird dazu verwendet, mehrere Schritte zu verknüpfen und zusätzliche Aktionen hinzuzufügen, die nach einem vorherigen Schritt ausgeführt werden sollen. Das Aber-Schlüsselwort kommt zum Einsatz, wenn eine Bedingung erfüllt sein muss, die sich von der erwarteten Standardfolge unterscheidet.
    In dem folgenden Beispiel ist die Verwendung beider Schlüsselwörter veranschaulicht:
# language: de
Funktionalität: Prüfung der Taschenrechner-Funktionen
  Regel: Grundlegende Rechenoperationen
    
    Szenario: Addition von zwei Zahlen
      Angenommen der Taschenrechner ist eingeschaltet
      Wenn ich 5 und 7 addiere
      Und das Ergebnis anzeigen lasse
      Dann sollte das Ergebnis 12 sein

    Szenario: Subtraktion von zwei Zahlen
      Angenommen der Taschenrechner ist eingeschaltet
      Wenn ich 10 von 15 subtrahiere
      Und das Ergebnis anzeigen lasse
      Dann sollte das Ergebnis 5 sein
      Aber das Ergebnis sollte nicht negativ sein
Code-Sprache: PHP (php)
  • Grundlage, Hintergrund, Voraussetzungen, Vorbedingungen
    Diese Schlüsselwörter werden verwendet, um gemeinsame Vorbedingungen für alle Szenarien in einer Funktionalität zu definieren. Dies können Schritte sein, die in jedem Szenario wiederholt werden, und helfen, Redundanzen zu vermeiden.
# language: de
Funktionalität: Prüfung der Taschenrechner-Funktionen
  Regel: Grundlegende Rechenoperationen
    
    Grundlage:
      Gegeben sei Der Taschenrechner ist eingeschaltet

    Szenario: Addition von zwei Zahlen
      Wenn ich 5 und 7 addiere
      Dann sollte das Ergebnis 12 sein

    Szenario: Subtraktion von zwei Zahlen
      Wenn ich 10 von 15 subtrahiere
      Dann sollte das Ergebnis 5 sein
Code-Sprache: PHP (php)

In diesem Beispiel ist die Verwendung der Grundlage besonders sinnvoll, da der Schritt (der Taschenrechner ist eingeschaltet) wiederholt wird.

  • Szenariogrundriss, Szenarien
    Das Schlüsselwort Szenariogrundriss wird verwendet, um einen allgemeinen Testfall zu erstellen, der mit verschiedenen Beispieldaten ausgeführt werden kann.
    Zudem dient das Schlüsselwort Beispiele dazu, verschiedene Kombinationen von Eingabedaten bereitzustellen:
# language: de
Funktionalität: Prüfung der Taschenrechner-Funktionen
  Regel: Grundlegende Rechenoperationen
    
    Szenariogrundriss:
      Angenommen der Taschenrechner ist eingeschaltet
      Wenn ich <Zahl1> und <Zahl2> addiere
      Dann sollte das Ergebnis <ErgebnisAddition> sein
      Beispiele:
        | Zahl1 | Zahl2 | ErgebnisAddition |
        | 5     | 7     | 12               |
        | 10    | 15    | 25               |

    Szenariogrundriss:
      Angenommen der Taschenrechner ist eingeschaltet
      Wenn ich <Zahl1> von <Zahl2> subtrahiere
      Dann sollte das Ergebnis <ErgebnisSubtraktion> sein
      Beispiele:
        | Zahl1 | Zahl2 | ErgebnisSubtraktion |
        | 5     | 7     | 2                   |
        | 10    | 15    | 5                   |
Code-Sprache: HTML, XML (xml)

Cucumber Features

  1. Reporting
    Cucumber-Reports sind detaillierte Zusammenfassungen der Testergebnisse, die Einblicke in den Testdurchlauf bieten und Entwickler:innen sowie anderen Stakeholder:innen den Fortschritt und Status der Anwendung verdeutlichen. Cucumber unterstützt verschiedene Formate wie HTML, JSON und XML für die Berichtsgenerierung.
  1. Integration von Cucumber mit Testberichts- und CI/CD-Tools
    Die Integration von Cucumber mit gängigen CI/CD-Tools wie Jenkins und GitLab CI/CD ist entscheidend für die Automatisierung des Testprozesses, die Überwachung von Testergebnissen und einen reibungslosen Software-Entwicklungslebenszyklus. Diese Integration ermöglicht effiziente Automatisierung, Testmanagement und Überwachung, um einen nahtlosen Ablauf von Build, Tests und Deployment sicherzustellen.
  1. Cucumber Hooks
    Hooks sind Funktionen in Cucumber, die vor oder nach bestimmten Szenarien oder Feature-Dateien ausgeführt werden. Sie ermöglichen es, vorbereitende oder aufräumende Schritte zu definieren, die vor oder nach der Ausführung von Tests durchgeführt werden sollen.
    Es gibt zwei Hauptarten von Hooks:
    • Before-Hooks: Diese werden vor jedem Szenario oder vor der gesamten Feature-Datei ausgeführt.    
    • After-Hooks: Diese werden nach jedem Szenario oder nach der gesamten Feature-Datei ausgeführt.
  1. Tags
    Tags ermöglichen die Markierung von Szenarien oder Feature-Dateien mit benutzerdefinierten Bezeichnungen. Diese Tags dienen dazu, eine Gruppierung von Szenarien zu ermöglichen oder bestimmte Tests in einem speziellen Kontext auszuführen. Tags werden mit dem (@) Symbol verwendet.
    Tags können über den folgenden Schlüsselwörtern platziert werden: Funktionalität, Szenario, Szenariogrundriss und Beispiele.
# language: de
@calculator @math
Funktionalität: Prüfung der Taschenrechner-Funktionen
  Regel: Grundlegende Rechenoperationen
  
    @addition
    Szenario: Addition von zwei Zahlen
      Angenommen der Taschenrechner ist eingeschaltet
      Wenn ich 5 und 7 addiere
      Und das Ergebnis anzeigen lasse
      Dann sollte das Ergebnis 12 sein
      
    @subtraction
    Szenario: Subtraktion von zwei Zahlen
      Angenommen der Taschenrechner ist eingeschaltet
      Wenn ich 10 von 15 subtrahiere
      Und das Ergebnis anzeigen lasse
      Dann sollte das Ergebnis 5 sein
      Aber das Ergebnis sollte nicht negativ seinCode-Sprache: CSS (css)
  1. Reguläre Ausdrücke
    Cucumber unterstützt die Verwendung von regulären Ausdrücken in Testschritten, um ein flexibles Muster für Platzhalter und Eingaben zu definieren.
  2. Datentabellen
    Datentabellen ermöglichen die Darstellung von Eingabedaten in tabellarischer Form innerhalb von Szenarien. Sie sind nützlich, wenn ein Schritt eine Liste von Daten oder Ausgaben in einer strukturierten Form akzeptieren oder anzeigen soll. Datentabellen werden durch Pipe-Zeichen (|) getrennt und können mehrere Zeilen haben:
# language: de
@calculator @math
Funktionalität: Prüfung der Taschenrechner-Funktionen
  Regel: Grundlegende Rechenoperationen
  
    @addition
    Szenario: Addition von zwei Zahlen
      Angenommen der Taschenrechner ist eingeschaltet
      Wenn ich die folgenden Zahlenpaare addiere
        | Zahl1 | Zahl2 |
        | 5     | 7     |
        | 4     | 12    |
        | 9     | 43    |
      Und das Ergebnis anzeigen lasse
      Dann sollten die Ergebnisse in der Reihenfolge korrekt sein
        | Ergebnis |
        | 12       |
        | 16       |
        | 52       |Code-Sprache: CSS (css)

Fazit

In diesem Wissensbeitrag hast du erfahren, was Behavior Driven Development ist und wie eng es mit Agilität verknüpft ist. Anhand des Beispiels von Cucumber habe ich demonstriert, wie Behavior Driven Development erfolgreich implementiert werden kann, wobei die Cucumber-Syntax eine effiziente Formulierung von Anforderungen als Tests ermöglicht. Du bist nun bestens über den Aufbau, die Schlüsselwörter sowie die Features von Cucumber informiert.

Letztlich komme ich zu dem Schluss, dass die Integration von Cucumber in den agilen Entwicklungsprozess eine effektive, transparente und kollaborative Software-Entwicklung im Rahmen von Behavior Driven Development ermöglicht. Durch das klare Festlegen von Anforderungen in ausführbaren Szenarien verbessern wir nicht nur die Kommunikation, sondern steigern auch die Qualität der Software in agilen Umgebungen.

Das könnte Dich auch noch interessieren

Implementierung von Event Storming Modellen mit Axon

Implementierung von Event Storming Modellen mit Axon

Wie überführt man eine Menge von Post-its in ausführbaren Code? Ein Pattern-basierter Ansatz kann hier helfen ...
Irisa Limani und Laura Sundara im Conciso Workgarden

Integrationstest-Set-up mittels Extensions vereinfachen

JUnit 5 bietet verschiedene Möglichkeiten, Tests zu erweitern. Wie du JUnit 5 Extensions verwendest, um das Set-up von Integrationstests zu ...
Das Nx-Monorepo - Verwalte Deine Anwendung in einem Repository

Das Nx-Monorepo – Verwalte Deine Anwendung in einem Repository

Ich zeige Dir in diesem Tutorial, wie Du mit einem Nx Monorepo Deine Anwendung mit mehr Organisation und weniger Duplikaten ...