Was ist Behavior Driven Development?
Samstag, 08. Oktober 2011 um 00:00 von Marco Emrich in Webentwicklung
Es gibt keinen großen Hype um dieses Konzept, das Behavior Driven Development (BDD) genannt wird. Zu Unrecht - möchte ich behaupten. Ich denke, dass fast jeder Entwickler von der Anwendung von BDD/TDD-Techniken stark profitieren könnte. Deswegen möchte ich Ihnen das Thema in diesem Beitrag ein wenig näher bringen. Alternativ können Sie sich auch das Video meines Pecha Kucha-Vortrags von der diesjährigen Seacon Was ist dran an Behavior Driven Developent? anschauen.
Automatisiertes Testen
Behavior Driven Development entstammt dem Umfeld des automatisierten Testens. Dass es Sinn macht, Software-Tests zu automatisieren, ist schon lange kein Insider-Tipp mehr. Früher brachten große QA-Abteilungen Wochen damit zu, eine komplexe Anwendung auf Herz und Nieren zu testen. An dieser Stelle genügt heute oft ein Knopfdruck und innerhalb einiger Minuten, liefert das Testwerkzeug einen Bericht über den Gesundheitszustand der Anwendung. Qualität und Aussagekraft variiert natürlich sehr, je nach eingesetzten Werkzeugen, Technologien und der Qualität der Tests. Fakt ist: Der Return of Investment (ROI) guter automatisierter Tests ist kaum zu schlagen.
Unit-Tests
Mit dem Einzug agiler Methoden um die Jahrtausendwende - allen voran eXtreme Programming (XP), verbreiteten sich automatisierte Tests auch auf einer ganz anderen Ebene. Die Rede ist von so genannten Unit-Tests. Diese testen nicht etwa wie Mitarbeiter einer QA-Abteilung, sondern arbeiten auf der Ebene des Quellcodes. Der Programmierer schreibt die Tests bereits während der Entwicklung. Ziel ist es nicht, Funktionalität aus Sicht eines Anwenders zu prüfen (etwa eine Story), sondern die korrekte Funktion einzelner Codeeinheiten (Units) sicherzustellen. Der Vorteil liegt auf der Hand: Der Programmierer kann zu jedem Zeitpunkt der Entwicklung sicherstellen, dass seine aktuellen Veränderungen keine neuen Fehler einführen. Sicherlich kennen Sie das Problem, dass eine Veränderung des Codes an einer Stelle einen Fehler an einer ganz anderen hervorrufen kann. Innerhalb von Minuten liefern Unit-Tests Gewissheit.
Viel weniger offensichtlich ist, dass Unit-Tests im Grunde kein Mittel zur Qualitätsicherung darstellen. Für Letzteres sind die oben beschriebenen Akzeptanztests da, die die Software prüfen wie ein Mitarbeiter einer Testabteilung. Unit-Test treffen nur Aussagen über die Fehlerfreiheit einer Codeeinheit, nicht über die Software im Ganzen. Sie helfen aber damit, einen Großteil der Programmierfehler schon sehr schnell nach ihrer Entstehung zu entdecken.
Das ist auch der eigentliche Vorteil! Das Beheben eines Bugs ist um so aufwändiger, je später er bemerkt wird. Der Programmierer kann Fehler zeitnah und damit schnell und kostengünstig beheben. Unit-Tests stellen also im Wesentlichen ein Mittel zu Erhöhung der Produktivität dar (Erdogmus 2005).
Test Driven Development (TDD)
Etwas weniger verbreitet als die Unit-Tests selbst, jedoch längst im Mainstream angekommen, ist die dazu-gehörige Methodik: das Test Driven Development. Kent Beck hat sie zusammen mit den Unit-Tests und einem passenden Framework/Seedwork (sUnit) erfunden oder zumindest als erster beschrieben (Fowler, Beck 1998). Die Methode ist auch fester Bestandteil des eXtreme Programming.
Die beiden wichtigsten Elemente des TDD sind das Test-First-Development und das Red/green/refactor-Mantra. Test-First-Development bedeutet, dass der Test zeitlich vor dem Code entwickelt wird, den es zu testen gilt. Das Red/green/refactor-Mantra spielt auf die optische Anzeige der meisten Unit-Test-Runner-Werkzeuge an. Rot signalisiert einen gebrochenen Test, Grün einen erfolgreichen. Die Idee ist,
- den Test zuerst zu schreiben und ihnen brechen zu lassen (rot);
- danach den Code zu schreiben, der den Test erfüllt (grün);
- und schließlich den Code zu refaktorieren um z.B. Lesbarkeit und Wartbarkeit zu verbessern (refactor).
Der offensichtliche Vorteil besteht darin, dass so sichergestellt wird, dass der Test auch wirklich testet. Grundsätzlich besteht sonst immer die Gefahr so genannter false positives. Das heißt der Test signalisiert Erfolg, testet den Code aber gar nicht.
Der weniger offensichtliche, aber schwerwiegendere Vorteil besteht darin, dass der Programmierer zunächst in die Rolle eines Kunden für seinen Code schlüpft. Er muss zuerst über die Verwendung des Codes, also über das Interface nachdenken, bevor er sich mit der Implementierung auseinandersetzt. Der konsequente Einsatz von TDD wird dadurch zu einer Technik für den systematischen Softwareentwurf - einer Designmethodik.
Meiner Meinung nach ist TDD einer der wichtigsten Säulen der modernen Software-Entwicklung. Es kann praktisch jedes Projekt davon profitieren - unabhängig davon, ob es einem agilen oder klassischen Prozess folgt.
Behavior Driven Development
Nun zum eigentlichen Kern dieses Blogbeitrags. Was ist denn nun Behavior Driven Development (BDD)?
Vereinfacht ließe sich sagen, dass es sich bei BDD um eine Weiterentwicklung des TDD handelt. David Astels (2007), einer der BDD-Pioniere, fasst es in folgende Worte:
Behavior Driven Development is what you are doing already, if you are doing Test Driven Development very well.
Dan North, der Namensgeber des Behavior Driven Developments ergänzt diese Sichtweise um weitere Aspekte, wie eine spezifische Methodik und die Verwendung von Story-Level-Frameworks - dazu gleich mehr (North 2006).
Etwas genauer betrachtet, besteht BDD aus vier miteinander verwobenen Aspekten:
- dem Vokabular
- den Frameworks
- der Methodik
- dem Abstraktionsgrad Story-Level
Das Vokabular
Die größte Schwierigkeit beim TDD ist es, zu verstehen, dass sich dabei eben nicht um ein Testwerkzeug, sondern im Wesentlichen um eine Designmethodik handelt.
It's not about testing - it's about design - specifying behaviour
(DenkZeit-Wiki: Behavior Driven Design, basierend auf Astel 2006)
Folks who do TDD for a while typically come to the conclusion that the only thing that TDD has to do with testing is the appearance of the word test in its name.
(Bellware 2008)
Zu behaupten Test-Driven-Development hat nicht mit Testen zu tun, klingt aber widersprüchlich und nicht gerade intuitiv (Ray 2006, Astel 2005). Verschärft wird dieses Problem durch das Vokabular der xUnit-Frameworks. Deswegen ändert Behavior Driven Development dieses Vokabular. Das Wort Test entfällt. Im Zentrum steht dagegen die Spezifikation. Eine Spezifikation beschreibt das gewünschte Verhalten (Behavior) einer Software.
Natürlich macht es in der Praxis keinen großen Unterschied, ob der Programmierer
assert_equals(3, x)
oder x.should be_equal(3)
schreibt. Das Ziel dieser Vokabularänderung ist es aber, gerade Anfängern des TDD die wichtigen Aspekte möglichst schnell zu vermitteln und den langwierigen Erfahrungsprozess zu verkürzen (BDD-Wiki: Introduction). In meiner Pecha Kucha von der diesjährigen Seacon beleuchte ich ebenfalls diese Thematik (Emrich 2011).
Die Frameworks
Mittlerweile haben sich einige Frameworks etabliert, die die Ideen des Behavior Driven Developments in Software gießen. Für die meisten industriell bedeutsamen Programmiersprachen gibt es gleich mehrere solcher BDD-Frameworks. Am Ende dieses Beitrags finden Sie ein kleine Liste mit Empfehlungen.
Über die Vorteile des verbesserten Vokabulars hinaus bieten diese Frameworks, eine Reihe zusätzlicher Features. Während über das geänderte Vokabular durchaus kontrovers diskutiert wird, so bieten diese neuen Features doch einen handfesten, feststellbaren Mehrwert (Emrich 2009). Dazu gehören beispielsweise Kontexte, direkte Integration von Mocks und Stubs, im- und explizites System Under Test, automatische Dokumentationsgenerierung u.v.m (Chelimsky 2010).
Story-Level-Frameworks & Methodik
Neben dem Vokabular bringt das BDD eine eigene Methodik mit, die eine ganzheitliche Outside-In Entwicklung darstellt. Outside-In bedeutet, dass die Entwickler, die ersten Spezifikationen auf relativ abstrakter, Anwender-naher Ebene beginnen, und sich dann Stück für Stück bestehenden API's annähern (Meszaros 2007, Wikipedia: Outside-in). Das heißt der erste Code fußt auf Klassen, Funktionen etc, die es noch gar nicht gibt. Möglich wird das durch Verwendung so genannter Mocks und Stubs, die reale Klassen imitieren.
Passend dazu gibt es BDD-Frameworks, die auf Story-Ebene arbeiten. Stories sind das Mittel der Wahl zur Aufnahme von Anforderungen in agilen Methoden wie z.B. Scrum oder XP. Daraus lassen sich sich dann leicht Szenarien zur Spezifikation ableiten. Hier ein Beispiel:
Funktionalität: Kunde-Login Als Kunde Möchte ich mich mit meinen Zugangsdaten einloggen Um an der Auktion teilnehmen zu können Grundlage: Bestehender Kunde Angenommen es gibt die folgenden Kunden: | email | kundennummer | password | | kunde@web.de | 123456 | top_secret | Szenario: Erfolgreiches Login mit E-Mail-Adresse Wenn ich auf die Login-Seite gehe Und ich "Login" mit "kunde@web.de" ausfülle Und ich "Passwort" mit "top_secret" ausfülle Und ich auf "Anmelden" drücke Dann sollte ich auf der Startseite sein Und ich sollte "Sie wurden erfolgreich eingeloggt" sehen
(Reimann 2011)
Bei diesen Szenarien handelt es nicht etwa nur um genau beschriebene Abläufe, sondern um tatsächlich ausführbaren Code für das Framework - hier Cucumber. Damit ermöglicht das BDD, den Kunden oder Business Analysten in die Entwicklung mit einzubeziehen. In Verbindung mit Outside-In-Entwicklung wird unnötiger Code vermieden und das Team programmiert nur, was wirklich gefordert ist (YAGNI-Prinzip aus dem XP). Leider ist damit auch ein großer Aufwand verbunden. Die Programmierer müssen zusätzlich so genannte Step-Definitions entwickeln, um natürliche Sprache und Programmiersprache zu verbinden.
BDD in der webmasters akademie
In der webmasters akademie haben wir uns gegen Story-Level-Frameworks entschieden und betreiben die Methodik eher pragmatisch, indem wir zwischen Outside-in- und Inside-out-Entwicklung wechseln - je nach Bedarf. Allerdings kann ich mir durchaus Projekte vorstellen, in denen es sinnvoll ist, einen Business Analysten im Team zu haben, der BDD-Specs lesen und schreiben kann (Martin 2010, 2011).
Fazit
Wenn Sie bereits erfolgreich TDD einsetzen, brauchen Sie im Grunde kein BDD!
ABER falls Sie Einsteiger sind, kommen Sie mit BDD sehr viel schneller ans Ziel. Sie erkennen früher, worauf es ankommt. BDD-Frameworks unterstützen Sie außerdem mit Features, die es Ihnen erleichtern, von Anfang an gute Spezifikationen zu schreiben.
(vgl. Emrich 2011)
Empfehlung
Haben Sie vielleicht Lust bekommen, tiefer in das Thema einzusteigen? In dem Fall rate ich Ihnen davon ab, noch mehr Theorie lesen als ich Ihnen hier schon zugemutet hab'. Machen Sie sich lieber die Hände schmutzig! Krempeln Sie die Ärmel hoch und schreiben Sie verhaltens-getriebenen Code! Suchen Sie sich dazu ein BDD-Framework in Ihrer Lieblingssprache und legen Sie los!
Hier habe ich Ihnen ein paar Links zu brauchbaren BDD-Frameworks zusammengestellt. Ich hoffe Ihre Programmiersprache ist dabei.
Ruby: RSpec2, Cucumber
JavaScript: Jasmine
Java: JDave
Groovy/Java: easyB
Scala/Java: ScalaTest
PHP: Behat, PHPSpec
.Net: SpecFlow
Wenn Ihnen der Beitrag gefallen hat, würde ich mich über einen Kommentar freuen und wenn nicht, müssen Sie mir unbedingt mitteilen wieso :)
viel Spaß beim Coden...
Quellen und Literaturhinweise
Astels D. (2003)
Test Driven Development. Prentice Hall. ISBN 0131016490.
Astels D. (2006)
A New Look at Test-Driven Development. siehe http://techblog.daveastels.com/files/BDD_Intro.pdf
Astels D. (Oktober 2007)
Beyond Test Driven Development: Behaviour Driven Development, Video, siehe http://www.youtube.com/watch?v=XOkHh8zF33o
BDD-Wiki: Introduction
Introduction, Wiki-Artikel betrachtet am 06.10.2011 unter http://behaviour-driven.org/Introduction, letzte Stand vom 15.09.2010 von Rimmer C.
Beck K. (Dezember 1998)
Simple Smalltalk Testing: With Patterns. Ursprünglich veröffentlicht als Kapitell 30 Simple Smalltalk Testing im Kent Beck's Guide to Better Smalltalk von Kent Beck und Donald G. Firesmith. Cambridge University Press. ISBN 9780521644372
Beck K. (2002)
Test Driven Development by Example. Addison-Wesley. ISBN 0-321-14653-0.
Bellware S. (Mai 2008)
Behavior-Driven Development. Artikel im CoDe Magazine Mai/Juni-Ausgabe 2008, siehe http://www.code-magazine.com/articleprint.aspx?quickid=0805061&page=1&printmode=true
Chelimsky D. , Astels D., Dennis Z. , Hellesoy A., Helmkamp B., North D. (Dezember 2010)
The RSpec Book: Behaviour Driven Development with RSpec, Cucumber, and Friends. Pragmatic Programmers. ISBN 978-1934356371
DenkZeit-Wiki: Behavior Driven Design
Wiki-Artikel, betrachtet am 07.10.2011 unter http://wiki.gungfu.de/Main/BehaviorDrivenDesign
Erdogmus H. (2005)
On the Effectiveness of Test-first Approach to Programming. Proceedings of the IEEE Transactions on Software Engineering. siehe http://nparc.cisti-icist.nrc-cnrc.gc.ca/npsi/ctrl?action=shwart&index=an&req=5763742&lang=en
Emrich M. (Januar 2010)
Angenehmere Tests für Finger und Augen - Einstieg ins Behaviour-driven Development mit Shoulda. Artikel im RailsWay-Magazin 01.2010. Software & Support Verlag. siehe http://it-republik.de/railsway/magazin-ausgaben/Enterprise-Rails-000335.html
Emrich M. (Juni 2011)
Was ist dran am BDD?, Video, Pecha Kucha von der Seacon 2011, siehe http://vimeo.com/groups/98525/videos/27393292
Fowler M.
Blog-Beitrag, betrachtet am 07.11.2011 unter http://www.martinfowler.com/bliki/Xunit.html
Martin R. C. (2009)
Clean Code - A Handbook of Agile Software Craftsmanship. Prentice Hall. ISBN 978-0-13-235088-4
Martin R. C. (2011)
Korrespondenz auf Twitter, siehe http://twitter.com/#!/marcoemrich
Meszaros (2007)
xUnit Test Patterns: Refactoring Test Code. Addison-Wesley. ISBN 978-0131495050.
North D. (2006)
Introducing BDD, Artikel aus dem Better Software magazine, Online-Version betrachtet am 06.10.2011 unter http://dannorth.net/introducing-bdd/
Ray K. (August 2006)
BDD. Blog-Beitrag als Antwort auf (Astels 2006), betrachtet am 06.10.2011 unter http://homepage.mac.com/keithray/blog/2006/08/12/
Reimann (Juni 2011)
Blog-Beitrag, betrachtet am 07.10.2011 unter http://dennisreimann.de/blog/programmiert-ihr-deutsch-nachgeladen/
Wikipedia: Behavior Driven Development
Wikipedia-Artikel, betrachtet am 06.10.2011 unter http://en.wikipedia.org/wiki/Behavior_Driven_Development
Wikipedia: Test-driven Development
Wikipedia-Artikel, betrachtet am 06.10.2011 unter http://en.wikipedia.org/wiki/Test-driven_development
Wikipedia: Outside-in Development
Wikipedia-Artikel, betrachtet am 06.10.2011 unter http://en.wikipedia.org/wiki/Outside-in_software_development
Tags: Programmierung , Unit Tests , TDD , BDD
Kommentare
-
Stephan
am Montag, 16. April 2012, 20:23
-
Marco Emrich
Hallo Stephan,
vielen Dank für den Hinweis. Du hast natürlich Recht in Ruby ist Cucumber neben RSpec DAS BDD-Framework schlechthin! Ich hab Deine Empfehlungen ergänzt.
Danke - Marco.
am Dienstag, 17. April 2012, 13:47
Tolle Einführung in die Thematik BDD! Bei den Empfehlungen würde ich aber definitiv noch Cucumber für Ruby aufführen - ist finde ich neben RSpec der quasi BDD-Standard :) und bei PHP habe ich noch gute Erfahrungen mit PHPSpec für PHP gemacht (analog zu RSpec für Ruby)...