Automatisiertes funktionales Testing in Java mit BDD, Cucucmber und Selenium

In der agilen Software-Entwicklung greifen immer mehr Firmen auf Entwicklungsmethoden wie testgetriebene Entwicklung (Test Driven Develepment – kurz: TDD) zurück, um bei stetig wechselnden Anforderungen eine hohe Qualität sicher zu stellen.

Ein dennoch immer wiederkehrendes Problem sind häufige Korrekturschleifen.

Diese resultieren oftmals aus unterschiedlichen Verständnisses eines Features zwischen Fachseite und Entwicklung, aber auch schwammig definierten Anforderungen.

BDD ist eine Methode die sich dieser Problematik stellt.

Behavior Driven Development?

Bei verhaltensgetriebener Softwareentwicklung (Behavior Driven Development – kurz: BDD) definiert die Fachseite die Anforderungen bzw. das gewollte Verhalten eines Features in Szenarien.

Diese Szenarien werden aus der Sicht eines Anwenders geschrieben und können sich auf ein Verhalten eines User-Interfaces oder auch auf Erwartungen an ein Backend-Service beziehen.

Sie ähnelt den User-Stories beim Extreme Programming, werden aber in einer bestimmten Syntax (z.B. Gherkin) geschrieben

Dadurch sind sie von der Fachseite und der Entwicklung eindeutig und verständlich lesbar und  können zusätzlich von Frameworks interpretiert werden.

Für die Entwicklung definieren die Szenarien die Akzeptanzkriterien eines Features

Vorteile:

  • Die Fachseite beschäftigt sich intensiver mit dem Ausformulieren des gewünschten Features
  • Missverständnisse und  Korrekturschleifen werden in der Regel dadurch vermieden oder zumindest vermindert
  • Eine gemeinsame Sprache für Fachseite und Entwicklung

Beispiel Syntax eines Features mit einem Szenario:

Feature: Login Feature
  Der Nutzer soll die Möglichkeit haben sich ein und auszuloggen.
  Scenario: User besucht eine Seite und ist nicht eingeloggt
    Given Benutzer besucht eine Seite
      And Benutzer ist noch nicht eingeloggt
     When Benutzer loggt sich mit korrekten Zugangdaten ein
     Then Benutzer wird auf seine persönliche Startseite umgeleitet
      And Willkommensnachricht wird angezeigt
 Scenario: User besucht eine Seite und seine Session ist abgelaufen
      ...

Und die Gurke?

Bei verhaltensgetriebener Softwareentwicklung kommt Cucumber ins Spiel.

Cucumber ist ein Framework, dass alle von der Fachseite geschriebene Features/Szenarien interpretiert und mit den vom Entwickler geschriebenen Software-Tests verbindet.

Also eine Schnittstelle zwischen Anforderung (Fachseite) und Implementierung (Entwicklung).

Cucumber ist damit in der Lage eine Übersicht aller Szenarien und den dazu gehörigen Tests zu generieren.

Hat zB. ein Entwickler für ein Feature/Szenario noch keinen Unit-Test geschrieben oder schlägt ein erstellter Test fehl, so erscheint das Feature in der Übersicht als fehlerhaft.

Die Fachseite und die Entwicklung können somit auf einem Blick sehen welche Features bereits fertig implementiert sind oder vielleicht nicht mehr funktioniert.

Ein Beispiel für ein Feature und dem dazugehörigen Test:

Feature

Feature: Login Feature
  Der Nutzer soll die Möglichkeit haben sich ein und auszuloggen.
  Scenario: User besucht eine Seite und ist nicht eingeloggt
    Given Benutzer besucht eine Seite
      And Benutzer ist noch nicht eingeloggt
     When Benutzer klickt auf login button
      And Benutzer gibt den Benutzernamen "testuser" ein
      And Benutzer gibt das Password "testpassword" ein
     Then Benutzer wird auf seine persönliche Startseite umgeleitet
      And Willkommensnachricht wird angezeigt

Test

public class TestLogin{
    @Given("Benutzer besucht eine Seite")
    public void userVisitsAnyPage(){
        // Mit Hilfe von Selenium auf die Seite navigieren
    }
    @And("Benutzer ist noch nicht eingeloggt")
    public void removeAllCookies(){
        // alle Cookies entfernen um sicherzustellen, dass der Nutzer nicht eingeloggt ist
    }
    @When("Benutzer klickt auf login button")
    public void userClicksOnLoginButton(){
        // Überprüfen ob der Loginbutton existiert und auf den Login Button klicken
    }
    @And("Benutzer gibt den Benutzernamen \"testuser\" ein")
    public void userEnteredTestUsersUsername(){
        // Überprüfen ob das Eingabe-Feld für den Benutzernamen existiert und den Wert "testuser" eintragen
    }
    @And("Benutzer gibt das Password \"testpassword\" ein")
    public void userEnteredTestUsersPassword(){
        // Überprüfen ob das Eingabe-Feld für das Password existiert und den Wert testpassword eintragen
    }
    @Then("Benutzer wird auf seine persönliche Startseite umgeleitet")
    public void userEnteredTestusersUsername(){
        // Selenium einen Timeout für die Navigation gewähren und überprüfen ob auf die persönliche Startseite umgeleitet worden ist
    }
    @And("Willkommensnachricht wird angezeigt")
    public void welcomeMessageShouldBeDisplayed(){
        // überprüfen ob die Willkommensnachricht angezeigt wird
    }
}


Cucumber Feature HTHML-Report:

Automatisierte Tests sind unverzichtbar!

Gerade in komplexen Systemen kann das Entwickeln ohne Tests zum verrückten Labyrinth werden.

Mit der Implementierung eines Features zerstört der Entwickler ein anderes Feature und merkt dies nicht.

Ungewolltes Verhalten im Back- oder Frontend können dadurch erst Tage oder Wochen später auffallen und erschwert die Fehlersuche.

Richtig eingesetzt können automatisierte Tests sogar dafür sorgen, dass keine fehlerhafte Software gebaut werden kann und der Entwickler gezwungen ist, die entstandenen Fehler sofort zu lösen.

Testgetriebene Entwicklung ist gerade in der agilen Entwicklung eine beliebte Methode um die Qualität und Sicherheit bei der Entwicklung neuer Features sicherzustellen.

Bei dieser Methode werden Software-Tests vor der eigentlichen Implementierung erstellt.

Diese Tests sind in der Regel Unit-Tests, welche die Implementierung einzelner Componenten im Backend testet.

Aber wie sieht es mit der Qualitätssicherung im User-Interface z.B. in Web-Applikationen aus?

In komplexen Systemen sind auch automatisierte User-Interface-Tests unverzichtbar!

Solche UI-Tests werden z.B. gerne mit Hilfe von Selenium (https://de.wikipedia.org/wiki/Selenium) erstellt und stellen die gewünschte Funktionalität sicher.

Cucumber mit Selenium

Bei der Entwicklung von Web-Applikationen kann Cucumber und Selenium perfekt kombinieren werden.

Die Fachseite definiert dabei die Szenarien aus der Sicht des Benutzers.

Die Entwicklung kann dann auf Basis der Szenarien die gewünschten Features implementieren und mit Hilfe von Selenium in den automatisierten Tests simulieren.

Dadurch wird auch das Verhalten eines User-Interfaces sichergestellt und von Cucumber in der generierten Übersicht angezeigt.

Fazit

Mit Behavior Driven Development wird Qualitätssicherung für das ganze Team ein wichtiges Thema.

Fehler fallen früher auf, die Effizienz wird durch Verminderung von Korrekturschleifen erhöht und die Auslieferung fehlerhafter Software deutlich vermindert.

Gerade in der agilen Entwicklung ist Behavior Driven Development mit Cucumber eine hilfreiche Ergänzung und kann gut mit testgetriebener Software-Entwicklung kombiniert werden.

Für das Extreme Programming geschriebene User-Stories können dabei ganz einfach in Szenarien umgeschrieben werden.

Ein sehr guter Anwendungsfall für Behavior Driven Development mit Cucumber ist die Entwicklung komplexer Web-Applikationen.

Hierbei kann nicht nur die Backend sondern auch die Frontend-Funktionalität sichergestellt werden.