Partner von:

Verhaltensgetriebene Software-Entwicklung

Arbeitsplatz [Quelle: pixabay.com, Autor: Picography]

Quelle: pixabay.com, Picography

Behavior Driven Development ist eine praktische Alternative zur testgetriebenen Software-Entwicklung - vorausgesetzt, man hat ein entwicklerfreundliches Framework. JGiven zum Beispiel.

Es gibt in der Software-Entwicklung eine einfache Regel: Je später ein Softwarefehler gefunden wird, desto teurer wird er. Die Explosion der ersten Ariane 5 wurde durch einen Softwarefehler ausgelöst und verursachte einen Schaden von 370 Millionen US-Dollar. Der Fehler ist leider erst nach dem Start der Rakete aufgetreten. Wäre der Fehler noch während der Entwicklung gefunden worden, hätte er mit geringem Aufwand behoben werden können. Es gibt viele Möglichkeiten, Fehler noch während der Entwicklung von Software zu finden. Das wichtigste Mittel dabei ist das Testen.

Testgetriebene Softwareentwicklung

In klassischen Software-Entwicklungsprozessen wird die Software erst nach deren Entwicklung in einer gesonderten Testphase durch Tester manuell getestet. Dieser Prozess ist allerdings sehr teuer und zeitaufwendig, da Fehler, die in der Testphase gefunden werden, eine rückwirkende Änderung der ja eigentlich schon fertigen Software bedeuten. In der sogenannten testgetriebenen Software-Entwicklung sind Tests hingegen ein fester Bestandteil der Entwicklung und nicht in eine separate Phase ausgelagert. Dadurch können Fehler wesentlich früher entdeckt und schneller behoben werden. Der wichtigste Punkt dabei ist, dass es sich nicht um manuell ausgeführte Tests handelt, sondern um automatisierte Tests, die in der Regel von Continuous-Integration-Servern (CI-Servern) kontinuierlich ausgeführt werden. Die testgetriebene Entwicklung hat jedoch einen Nachteil: Die Software-Entwickler testen die von ihnen geschriebene Software selbst. Die Entwickler sind aber oft nicht diejenigen, die die Anforderungen an die Software stellen. Dies kann dazu führen, dass die Software zwar alle Tests erfolgreich absolviert, sie sich aber trotzdem nicht so verhält, wie eigentlich vom Fachexperten gewünscht. Die Fachexperten können diesen Fehler in der Regel allerdings erst bemerken, wenn sie die Software benutzen, also wenn die Entwicklung des jeweiligen Features schon abgeschlossen ist. Da die Tests selbst in einer Programmiersprache wie zum Beispiel Java geschrieben sind, ist es für Fachexperten ohne Programmierkenntnisse unmöglich, die Tests vorher auf ihre Korrektheit zu überprüfen.

Verhaltensgetriebene Software-Entwicklung

Genau an der Stelle setzt die sogenannte verhaltensgetriebene Software-Entwicklung (engl. Behavior Driven Development, BDD) an. Sie ist eine Weiterentwicklung der testgetriebenen Entwicklung, die die Fachexperten in den Software-Entwicklungsprozess besser einbindet. Bei der verhaltensgetriebenen Software-Entwicklung werden Tests nicht alleine von Software-Entwickleren entworfen, sondern in enger Zusammenarbeit mit den jeweiligen Fachexperten. Damit Fachexperten und Software-Entwickler gemeinsam das Verhalten der Anwendung beschreiben können, muss eine einheitliche, von allen Seiten verstandenen, Sprache und Notation verwendet werden. Als Sprache wird dabei immer die Fachsprache verwendet, die auch die Fachexperten selbst verwenden. Jeder Begriff der Fachsprache sollte dabei genau definiert und eindeutig sein. So sollten zum Beispiel keine Synonyme verwendet werden. Also Notation hat sich die Given-When-Then-Notation in der Praxis bewährt. Dabei wird ein bestimmtes Verhalten der Software anhand eines konkreten Beispiels in einem sogenannten Szenario beschrieben, das aus drei Teilen besteht.

Im ersten Teil wird die Ausgangssituation bzw. die Vorbedingung beschriebenen (Given). Der zweite Teil beschreibt die Aktion, die in dem Softwaresystem ausgelöst wird (When). Im letzten Teil werden dann die gewünschten Ergebnisse und Nachbedingungen beschrieben (Then). Als Beispiel wollen wir das Verhalten eines einfachen Kaffeeautomaten beschreiben. Wir formulieren hierzu folgendes Szenario:

Quelle: TNG

Man erkennt schnell, dass ein Szenario eine klar definierte Struktur hat. Dies ist wichtig, damit das Szenario später automatisiert ausgeführt werden kann. Neben einer kurzen Zusammenfassung besteht ein Szenario dabei immer aus mehreren ‘Schritten’. Jeder Schritt wird mit einem vordefinierten Einleitungswort begonnen. Dadurch ist klar, ob es sich um eine Vorbedingung (angenommen), eine Aktion (wenn) oder eine Nachbedingung (dann) handelt. Das Wort ‘und’ kann verwendet werden, um zusätzliche Schritte zu definieren. Das obige Szenario beschreibt den Normalfall, das heißt alle Vorbedingungen zum Produzieren eines Kaffees sind erfüllt. Interessanter sind oft allerdings die Rand- bzw. Fehlerfälle (engl. corner cases), da es hier öfter zu Missverständnissen kommen kann. Was soll zum Beispiel passieren, wenn keine Kapsel im Automat ist? Soll er dann einfach nur heißes Wasser ausgeben oder den Dienst ganz verweigern? Im letzteren Fall müsste der Automat einen Erkennungsmechanismus für die Anwesenheit einer Kapsel besitzen. Oder was soll passieren, wenn der Wassertank nur 100 ml (oder genau 200 ml) Wasser enthält? All diese Sonderfälle sollten durch entsprechende Szenarien abgedeckt werden.

Automatisiertes Ausführen von Szenarien

Das gemeinsame Formulieren von Test-Szenarien ist sehr hilfreich, um im Vorhinein Missverständnisse zwischen Fachexperte und Software-Entwickler zu vermeiden. Software wird allerdings ständig angepasst und weiterentwickelt. Daher ist es wichtig, dass die einmal formulierten Szenarien regelmäßig gegen die Software getestet werden. Da ein manuelles Überprüfen, wie oben schon beschrieben, zu zeitaufwendig ist, müssen die Szenarien automatisiert ausführbar sein. Bei jeder Softwareänderung können dann alle Szenarien durch einen CI-Server automatisch getestet werden. Dadurch wird garantiert, dass sich die Software weiterhin wie spezifiziert verhält. Man spricht in diesem Zusammenhang auch von ‘lebender’ Dokumentation, also Dokumentation, die nicht veraltet.

Damit Szenarien automatisiert ausgeführt werden können, müssen sie an ausführbaren Code gebunden werden. Zu diesem Zweck verwendet man in der Regel ein Framework, das dies übernimmt. Eines der bekanntesten Frameworks in diesem Umfeld ist Cucumber. In Cucumber werden Szenarien in sogenannten Feature-Dateien geschrieben. Dies sind einfache Text-Dateien, in denen in der Regel ein ganzes Feature anhand mehrerer Szenarien beschrieben wird. Um Szenarien nun ausführen zu können, muss für jeden Schritt des Szenarios eine entsprechende Implementierung angeben werden. In Java schreibt man hierzu eine oder mehrere Klassen, die in etwa so aussehen:

Quelle: TNG

Für jeden Schritt in einem Szenario muss genau eine Methode existieren, die genau definiert, was bei der Ausführung des Schrittes passieren soll. Diese Methoden werden nun von Cucumber ausgeführt, wenn der jeweilige Schritt an der Reihe ist. Damit Cucumber weiß, welche Methode zu welchem Schritt gehört, müssen die Methoden mit Annotationen versehen werden. Für jede Schrittart gibt es dabei eine Annotation: @Given, @When und @Then. Mit der Annotation definiert man einen regulären Ausdruck. Eine Schritt-Methode wird genau dann von Cucumber ausgeführt, wenn das Muster, das der reguläre Ausdruckbeschreibt, auf den Text des Schrittes passt. Wie man an der zweiten Methode sieht, können Schritt-Methoden auch Parameter haben. Diese werden im regulären Ausdruck durch Gruppen mittels runder Klammern ausgedrückt.

nach oben

Stipendiaten und Alumni von e-fellows.net können kostenlos oder ermäßigt zahlreiche Online-Kurse belegen oder an Seminaren teilnehmen.

Verwandte Artikel

Hol dir Karriere-Infos,

Jobs und Events

regelmäßig in dein Postfach

Kommentare (0)

Zum Kommentieren bitte einloggen.

Das könnte dich auch interessieren