Given/When/Then und Beispieltabellen mit dem Robot Framework

3 Kommentare

Beim ATDD (Acceptance Test Driven Development – Fachtest-getriebene Entwicklung) und BDD (Behaviour Driven Development – Verhaltensgetriebene Entwicklung) ist folgende Syntax weit verbreitet, um vor- und nachgelagerten Bedingungen eines Tests zu formulieren:

  1. Given: Die statischen Vorbedingungen
  2. When: Das Verhalten, das zu testen (bzw. zu spezifizieren) ist
  3. Then: Die Ergebnisse des Verhaltens bei gegebenen Vorbedingungen

In diesem Zusammenhang wird auch gerne von ausführbaren Spezifikationen gesprochen, allerdings ist es bis dahin noch ein weiter Weg, oder?

Das Ziel ist es ein Verhalten so beschreiben zu können, dass es zugleich Spezifikation und Test ist. Dadurch entfällt die in Projekten immer entstehende Divergenz zwischen den Spezifikationen und dem was ein System tatsächlich tut.

Neben der weitgehen natürlichsprachlichen Testbeschreibung wird das genaue Verhalten aber erst durch weitere Beispiele verständlich. Diese unterscheiden sich oft nur in Details, sodass sich hier die tabellarische Form sehr empfiehlt. Die Kombination aus Verhaltensbeschreibung durch die Given/When/Then-Struktur in Verbindung mit weiteren Beispieltabellen erscheint hierbei zur Zeit ideal. Sie enthält alle technischen Details, um den Fachtest automatisieren zu können, ist kompakt genug, um übersichtlich zu bleiben und ist nicht zuletzt auch für den Fachbereich verständlich, sodass sie sehr gut als Diskussionsgrundlage genutzt werden kann. Eventuell kann sie sogar vom gesamten Team zusammen mit dem Fachbereich in einem sogennanten „Specification Workshop“ erstellt werden (siehe auch „Bridging the Communication Gap“, von Gojko Adzic).

Unterstützt wird die Struktur momentan z.B. sowohl von FITNesse als auch Cucumber unterstützt.

Mit der momentan aktuellsten Version des Robot Frameworks (2.1.2) gibt es eine verbesserte Unterstützung für die „umgangssprachliche“ Definition von Testfällen:

  • „Given“, „When“, „Then“ und „And“ werden bei User Keywords am Anfang ignoriert
  • Parameter können in Keywords eingebettet werden

Dadurch lassen sich nun wunderschön ausführbare Spezifikationen formulieren. Hier ein Beispiel:

*** Settings ***
Resource         ${RESOURCES}/BDD.txt
 
*** Keyword ***
Example
    [Arguments]  ${periodClosed}  ${periodOpenAndModified}  ${importDay}  ${oldManagerValidUntil}  ${newManagerValidFrom}
 
    Given initialized criteria for bonus commercial
    And a branch B with branch manager M_OLD and employee E1
    And evaluation for E1 for period ${periodClosed} which is closed
    And evaluation for E1 for period ${periodOpenAndModified} which is open and modified
 
    When M_NEW becomes new manager of branch B
    And import service is called on ${importDay}
 
    Then the new branch manager of branch B is M_NEW valid from ${newManagerValidFrom}
    And branch manager M_OLD manages employee E until ${oldManagerValidUntil}
    And branch manager M_NEW manages employee E from ${newManagerValidFrom}
    And Evaluations for E1 still have the same content
 
| *Test Case* | | *Closed Period*        | *Open Period*          | *Run Import On* | *Old Manager Stops* | *New Manager Starts* |
| 1 | Example   | 1.11.2009 - 30.11.2009 | 1.12.2009 - 31.12.2009 | 11.11.2009      | 30.11.2009          |  1.12.2009
| 2 | Example   | 1.11.2009 - 30.11.2009 | 1.12.2009 - 31.12.2009 |  1.11.2009      | 31.10.2009          |  1.11.2009
| 3 | Example   | 1.11.2009 - 30.11.2009 | 1.12.2009 - 31.12.2009 |  1.12.2009      | 30.11.2009          |  1.12.2009

So hat man eine sehr komprimierte und von vielem, unnötigen Ballast befreite ausführbare Spezifikation. Fast schon unglaublich, dass sich das tatsächlich ausführen lässt:

  • Das Beispiel ist eine Robot Test Suite, welche ein User Keyword „Example“ und drei Test Cases „1“, „2“ und „3“ enthält
  • Während die Test Cases den „data-driven-style“ verwenden, benutzt das User Keyword den neuen „behaviour-driven-style
  • Durch die Verwendung des reinen Textmodus braucht man keinen externen Editor. Im Gegenteil, die RIDE (Robot IDE) hat die unangenehme Angewohnheit die User Keywords unter den Test Cases zu speichern, was normalerweise auch sinnvoll, in diesem Fall aber dem Leseverständnis abträglich ist.
  • Einige Parameter in den User Keywords werden parametrisiert, wie z.B. ${importDay}, andere werden für diesen Testfall vorgegeben, wie z.B. der Name der Niederlassung B. Es ist essentiell die Beispieltabelle auf die relevanten Daten zu beschränken, damit diese übersichtlich bleibt.
  • Das User Keyword „Examples“ wird in jeder Test Suite neu definiert. Da Robot aber bei multiplen Definitionen immer derjenigen aus der aktuellen Suite den Vorrang einräumt stellt dies kein Problem dar, ganz im Gegenteil, so kann das Format der Beispieltabelle über alle Test Suites konsistent gehalten werden.
  • Die Beispieltabelle nutzt das Pipesymbol „|“ zur Abtrennung der Spalten. Dies ermöglicht die Spalten zu benennen, die Titel haben keine Auswirkung auf die Parameterübergabe, allein die Reihenfolge der Parameter muss mit der Zeile „[Arguments]“ übereinstimmen.
  • Die konkreten Testfälle in der Beispieltabelle sind einfach durchnummeriert; dies erhöht die Kompaktheit der Tabelle.
  • Das Setup und Teardown des Tests muss ein wenig versteckt im ersten User Keyword stattfinden (hier „initialized criteria for bonus commercial“). Andrerseits interessiert das fachlich ja auch nicht, wie ein System in einen definierten Ursprungszustand versetzt wird.
  • Die ausführbaren Spezifikationen können durch eine Verzeichnisstruktur gruppiert und User Stories zugeordnet werden.

Wie werden die fast natürlichen Sätze nun automatisiert? Dies sei am Beispiel der ersten Nachbedingung verdeutlicht. Die Resource-Datei BDD.txt enthält alle User Keywords, welche diese ausführbare Spezifikation ausführbar machen:

*** Settings ***
Library          de.codecentric.fourtexx.robot.ModelKeyword
 
*** Keywords ***
the new branch manager of branch ${branch} is ${manager} valid from ${newManagerValidFrom}
	Assert Branch Manager Valid From  ${branch}  ${manager}  ${newManagerValidFrom}

Man beachte, dass nicht nur das Datum parametrisiert ist, sondern auch der Name der Niederlassung und des Leiters der Niederlassung. Im konkreten Beispiele würden hier die Parameter B, M_NEW und (je nach Test Case) 1.12.2009 oder 1.11.2009 übergeben. Das hier definierte User Keyword ist nicht viel mehr als die Weiterleitung auf ein in Java implementiertes User Keyword. Dort kann dann nach belieben getan werden, was getan werden muss, um sicherzustellen, dass die geforderte Fachlichkeit erfüllt ist.

public void assertBranchManagerValidFrom(String branch, String manager, String validFrom) throws Exception  {
  // ...
}

Fazit: Mit den neuen Möglichkeiten von Robot 2.1.2 zieht es meiner Meinung nach mindestens mit den anderen Kandidaten im Rennen gleich. Die gefundene Möglichkeit ausführbare Spezifikationen inklusive anghängter Beispieltabelle in Textform zu formulieren scheint ideal, um Spezifikationen, Beispiele und Test wirklich auf ein Artefakt zusammenzuführen.

Andreas Ebbert-Karroum

Andreas Ebbert-Karroum ist Agile Principal Consultant bei codecentric und Product Owner von CenterDevice.

Share on FacebookGoogle+Share on LinkedInTweet about this on TwitterShare on RedditDigg thisShare on StumbleUpon

Kommentare

  • Lisa Crispin

    Nice! I haven’t used Robot Framework before, I’ve only seen demos, but I like that you can do it in a BDD style.

    You say you’re using a plain text editor, but you mention the Robot IDE, how does that fit in?

  • Andreas Ebbert-Karroum

    Hi Lisa,

    the Robot Framework supports three different formats for the test suites and test cases: HTML, tab separated (TSV), reStructuredText (reST – a python thing) and plain text. The content and sematic is equivalent between all choices and can be converted converted between any of the formats.

    RIDE supports HTML, TSV and plain text. I think it’s really useful for the first two, but if you’re dealing with plain text, a text editor (like Notepad++ or vi) is all you need. If you want to use some special plain text layout as above, it is even counter-productive to use RIDE, since it changes the order of the element, and also displays the table in a different way. The test case still works, but it’s much harder to read.

    Greetings,
    Andreas

  • Thomas Jaspers

    17. November 2009 von Thomas Jaspers

    This is really a very nice solution you found here in the end and it is a good example why I really like the Robot Framework that much: It simply gives you a lot of possibilities without getting too complex, even if it was quite tricky in this case I have to admit ;).

    @Lisa: Regarding RIDE it is probably true that it is more useful for HTML-style test-definitions, but there it is becoming really more and more powerful as it has nowadays some „Eclipse-like“ features like „auto-completion“ for keywords and also showing help on keywords, etc. … whenever I am doing data-driven style test definitions RIDE is definitly my first choice.

Kommentieren

Deine E-Mail-Adresse wird nicht veröffentlicht. Erforderliche Felder sind mit * markiert.