Akzeptanztests – Geliefert wie bestellt!

Keine Kommentare

Immer wieder kommt es vor, dass ein gefordertes Feature am Ende anders aussieht als es sich die Stakeholder in ihren Köpfen vorgestellt haben. Diese Situationen sind nicht ungewöhnlich und treten sowohl in Festpreis- als auch agilen Projekten auf. Solche Situationen sind nicht nur teuer und stressig, sondern auch frustrierend für alle Projektbeteiligten. Zusätzlich zu der Frustration ist so eine Situation auch noch ineffizient und mitunter auch gefährlich für den Projektablauf, wenn das Release unmittelbar bevorsteht. Vielleicht können Akzeptanztest helfen, Frust abzubauen?

Man stelle sich vor, die Abweichung der Vorstellung des Stakeholders und der Implementierung wäre nicht nur eine Kleinigkeit und das Feature wurde von den Entwicklern komplett anders verstanden und auch implementiert als es sich der Stakeholder ursprünglich vorgestellt hat. Was ist in so einer Situation zu tun? Den Releasetermin verschieben? Das Feature mit Hängen und Würgen irgendwie noch fertigstellen? Egal für welche der beiden Optionen man sich entscheidet, das Problem wird nicht dauerhaft gelöst.

Genau an dieser Stelle wird es spannend. Idealerweise sollte das Team den Prozess reflektieren und kritisch hinterfragen. Leider wird genau das in den meisten Fällen aber nicht getan. Dieser Artikel setzt an dieser Stelle an und gibt mit Akzeptanztests ein Mittel an die Hand, um diese Situationen besser zu lösen.

Was sind eigentlich Akzeptanztests?

Akzeptanztests lassen sich einfach am Beispiel des Testing Frameworks JBehave erklären. JBehave verwendet einen BDD-Ansatz (Behaviour Driven Development). Durch Verwendung von BDD kommen im Vergleich zu einem einfachen Unit-Test zwei wesentliche Änderungen ins Spiel: Anstatt die zu testende fachliche Anforderung zum Beispiel durch einen Methodennamen abzubilden, wie es bei Unit Tests der Fall ist, wird sie in einer eigens dafür vorgesehenen Story-Datei niedergeschrieben. Diese Story ist eine mit Schlüsselworten versehene Textdatei und beschreibt die fachlichen Anforderungen anhand von Beispielen mit Hilfe dieser Schlüsselwörter. Die folgenden Zeilen zeigen ein Beispiel einer Story-Datei:

Scenario: trader is not alerted below threshold
Given a stock of symbol STK1 and a threshold of 10.0
When the stock is traded at 5.0
Then the alert status should be OFF

Das einleitende Schlüsselwort Scenario vor jedem Given-When-Then-Block beschreibt einen Testfall. Im Anschluss daran wird das Verhalten durch mehrere Given-, When- und Then-Zeilen abgebildet. Am Ende des Artikels befinden sich zwei weiterführende Links, die sich der Formulierung solcher Testfälle widmen.Diese natürliche Sprache der Anforderungsbeschreibung ermöglicht eine auf die Fachlichkeit fokussierte Diskussion mit den Stakeholdern.

Im nächsten Schritt kommen die Steps ins Spiel, um Story und Java-Testcode miteinander in Beziehung zu setzen.

public class TraderSteps {
 
    private Stock stock;
 
    @Given("a stock of symbol $symbol and a threshold of $threshold")
    public void aStock(String symbol, double threshold) {
        stock = new Stock(symbol, threshold);
    }
 
    @When("the stock is traded at $price")
    public void theStockIsTradedAt(double price) {
        stock.tradeAt(price);
    }
 
    @Then("the alert status should be $status")
    public void theAlertStatusShouldBe(String status) {
        ensureThat(stock.getStatus().name(), equalTo(status));
    }
}

Wie zu erkennen ist, erfolgt das Mapping der Story-Datei auf den Java-Testcode anhand von Schlüsselwörtern und zugehörigen Annotationen. Die annotierten Testmethoden können dadurch sehr angenehm innerhalb der Story-Dateien mittels Autocompletion verwendet werden. Das vereinfacht die Wiederverwendung einzelner Steps.

Ganz angenehm ist es auch, sich die Java-Testmethoden aus den zuvor formulierten Story-Dateien erzeugen zu lassen. Durch ein einfaches Ausführen der Tests zu einer Story-Datei werden Methoden Rümpfe erzeugt, sofern noch keine passenden annotierten Methoden vorhanden sind. Daher empfiehlt es sich, zuerst die Akzeptanztests schriftlich zu formulieren und dann den Testcode dazu zu schreiben.

Durch den starken fachlichen Fokus der Akzeptanztests sind sie normalerweise auf Ebenen unterhalb der GUI angesiedelt. Die Kombination mit anderen Tools wie zum Beispiel Selenium ermöglicht es auch, Akzeptanztests direkt auf der GUI-Ebene zu verwenden. Diese Verwendung an vorderster Front ist naheliegend, da es für weniger technische Stakeholdern wie zum Beispiel Product Ownern oder Anwendern einfacher ist, Tests mit Hilfe der Benutzeroberfläche zu formulieren. Sie verknüpfen fachliche Anforderungen meistens in Form von Klickpfaden und Anwendungsfällen innerhalb einer Benutzeroberfläche.

Einerseits ist die Verwendung von Akzeptanztests auf GUI-Ebene naheliegend, da dadurch einfacher gemeinsam Testszenarien erfasst werden können. Stakeholder wissen, wann und auf was sie klicken möchten, und welche Ergebnisse sie erwarten. So lässt sich schnell eine deutlich größere Anzahl an Akzeptanztests formulieren, als würde die Betrachtung des Systems auf einer “tieferen” Ebene ansetzen. Auf der anderen Seite könnten GUI-Tests allerdings zu fragileren Tests, die möglicherweise schon bei kleineren Änderungen (wie zum Beispiel dem Aussehen) an der GUI nicht mehr funktionieren könnten. Mit den eigentlichen fachlichen Anforderungen hat das mitunter gar nichts zu tun. Es kann allerdings auch darauf hinauslaufen, dass Akzeptanzkriterien einzig und allein in eine Überprüfung von Klickpfaden ausarten. Darauf ist zu achten und gegebenenfalls gegenzusteuern. Auch das hat mit dem eigentlichen Zweck des Testens von fachlichen Anforderungen wenig zu tun und sollte sich somit gründlich überlegt werden.

Eine detaillierte Beschreibung des ATDD (Acceptance Test Driven Development) und dessen Vorgehensweisen würde den Rahmen sprengen, daher sei an dieser Stelle auf das Buch von Markus Gärtner: “ATDD by Example: A Practical Guide to Acceptance Test-Driven Development“ verwiesen.

Und was bringen diese Akzeptanztests?

Akzeptanztest bzw. die Akzeptanztest getriebene Entwicklung schließt die Lücke der auseinander laufenden Vorstellungen bzw. Anforderungen und bringt den Stakeholder und die Entwickler noch vor Beginn der Implementierung eines Features an einen Tisch. Ziel dieser Abstimmung ist die Formulierung testbarer Akzeptanzkriterien für die jeweils zu entwickelnde User Story.

schulz_abb1

Durch diese gemeinsame Abstimmung und Formulierung der Kriterien wird ein gemeinsames Verständnis der zu entwickelnden Story geschaffen und viele Unklarheiten schon vor Beginn der Entwicklung aus dem Weg geräumt. Auch fachliche Unstimmigkeiten, die während der Implementierung auffallen, kommen durch die Verwendung der Akzeptanzkriterien deutlich früher zum Vorschein und können auf dieser gemeinsamen Basis mit dem Stakeholder besprochen und korrigiert werden.

Des weiteren führt es dazu, dass eine gemeinsame Sprache (engl. Ubiquitous Language) entsteht und dadurch die Gefahr des Auseinanderlaufens zwischen dem Code und der Domäne deutlich verringert wird. Diese gemeinsame Sprache vereinfacht die Wartung der Software erheblich. Wie in der vorherigen Abbildung zu erkennen, wird durch das Mittel der Akzeptanztests eine Feedback-Schleife geschaffen, die vor und auch während der Implementierung immer wieder durchlaufen wird. Vor der Implementierung, indem die testbaren Akzeptanzkriterien niedergeschrieben werden und während der Implementierung, um über Unklarheiten zu sprechen und gegebenenfalls fehlende Anforderungen hinzuzufügen. Ein weiterer nicht außer Acht zu lassender Vorteil dieses Vorgehens ist die Automatisierung dieser Akzeptanztests und eine jederzeit korrekte Spezifikation der Software. Neuen Projektmitgliedern fällt es in der Regel einfach, den Code zu verstehen. Den Bezug zur Fachlichkeit herzustellen ist dagegen deutlich schwieriger, da ihnen das Wissen über die Domäne fehlt. An dieser Stelle beginnt normalerweise das Wälzen von Dokumenten und Befragen von Projektbeteiligten. Leider ist oft der Fall, dass nicht alle Entscheidungen dokumentiert wurden und im schlimmsten Fall die beteiligten Projektmitglieder und Wissensträger nicht mehr verfügbar sind. Die Spezifikation in Form der Story-Dateien sorgt an dieser Stelle für Abhilfe. Es müssen weniger oder auch gar keine Leute befragt und weniger Dokumente gewälzt werden. Stattdessen kann der Bezug zur Fachlichkeit direkt im Source-Code hergestellt werden. Unterm Strich wird durch Akzeptanztests die Einarbeitung neuer Projektmitglieder erleichtert.

Zusammenfassung

Akzeptanztests bzw. die Akzeptanztest getriebene Entwicklung stellt ein sehr effektives Mittel dar, um Features so zu entwickeln, wie sie von den Stakeholdern gewünscht sind. Ein Auseinanderlaufen zwischen Anforderungen in den Köpfen der Stakeholder und deren Implementierung wird durch das gemeinsame Erarbeiten der Testszenarien effektiv verhindert.Zusätzlich werden Unstimmigkeiten frühzeitig aufgedeckt und können dadurch im Anfangsstadium der Entwicklung behoben werden. Das hat eine Verringerung der Kosten durch ein Gegensteuern und eine Risikominimierung zur Folge. Auch der Stress vor Sprintende oder geplanten Releases kann dadurch deutlich verringert werden. Mit Hilfe von Frameworks wie zum Beispiel JBehave ist es sehr einfach möglich, seinen Testfokus auf die Fachlichkeit zu legen und sie anhand von konkreten Beispielen zu formulieren und zu erklären. Als angenehmes Mitbringsel gibt es zusätzlich eine jederzeit korrekte Spezifikation der Software und man kann sich das Pflegen von Dokumenten größtenteils sparen. Auf Grund der zahlreichen Vorteile gegenüber einer Nicht-Akzeptanztest-getriebenen Entwicklung ist meine Empfehlung ganz klar: Nutzen Sie dieses Hilfsmittel und verbessern Sie dadurch den Entwicklungsprozess für alle Projektbeteiligten.

Tipp: Dieser Text entstand ursprünglich für eine Ausgabe des Softwerker-Magazins, das die codecentric kostenlos herausgibt. Mehr Informationen gibt es hier.

Mehr zum Thema

  1. https://gojko.net/2015/02/25/how-to-get-the-most-out-of-given-when-then/
  2. https://www.it-agile.de/fileadmin/docs/veroeffentlichungen/Artikel_JS_04_09_FIT.pdf
  3. https://blog.codecentric.de/2011/03/automatisierte-akzeptanz-tests-mit-jbehave/
  4. https://www.ebgconsulting.com/blog/using-given-when-then-to-discover-and-validate-requirements-2/
  5. http://www.informatik-aktuell.de/entwicklung/methoden/einfuehrung-in-acceptance-test-driven-development-atdd.html
  6. http://de.slideshare.net/tcmak/atdd-in-practice
  7. http://de.slideshare.net/ehendrickson/introduction-to-acceptance-test-driven-development-3491703
  8. https://dzone.com/articles/continuous-testing-selenium
  9. Markus Gärtner, ATDD by Example:A Practical Guide to Acceptance Test-Driven Development, Addison-Wesley, 2012
Bennet Schulz

Bennet ist IT Consultant und Entwickler mit Vorliebe für Java EE, Enterprise Integration und API Management. In seiner Freizeit ist er an mehreren Java-User-Group-Aktivitäten, der Organisation der JavaLand Konferenz, sowie des Jugend hackt Nord und der lokalen Hamburger Devoxx4Kids Veranstaltungen beteiligt. Auf blog.codecentric.de und bennet-schulz.com bloggt er regelmäßig über seine Projekte und verschiedene Java-Themen.

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

Kommentieren

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