Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige
Lesedauer 16 Min.

Dokumentation und Test in einem

Mit SpecFlow kommt das Behavior-Driven-Development-Prinzip ins eigene Projekt.
© dotnetpro
Das automatisierte Testen verbreitet sich immer mehr. Sowohl Vorteile als auch Notwendigkeit haben sich herumgesprochen. Verständlicherweise werden Projekte ohne automatisierte Tests kritisch beäugt. Dabei ist der gesamte Zyklus, Software oder Komponenten zu designen, zu implementieren und anschließend zu testen, alles andere als einfach. Ganz im Gegenteil ist es keine Übertreibung zu behaupten, dass der gesamte Prozess komplex ist, da viele Personen, Teams und Technologien ineinandergreifen müssen, damit alles reibungslos funktioniert.Es ist vorteilhaft, wenn sich im besten Fall Tester zu den Entwicklern gesellen, um Testfälle und Testszenarien zu verbessern. Softwareentwicklungsprozesse haben sich dahingehend weiterentwickelt. Hier kommt Behavior Driven Development (BDD) ins Spiel. BDD spielt eine entscheidende Rolle, da es die Kommunikationslücke zwischen den wichtigsten Stakeholdern eines Softwareprojekts minimiert – zum Beispiel zwischen Product Owner, Entwicklern und Testern.Hier kommt SpecFlow ins Spiel, ein Tool für automatisierte Tests nach dem BDD-Prinzip. Knapp zusammengefasst ermöglicht es SpecFlow .NET-Teams, automatisierte Akzeptanztests als sogenannte geschäftsfähige Spezifikationen zu definieren, zu verwalten und auszuführen. Damit sind Spezifikationen gemeint, die weniger technischer Natur sind, sondern natürliche Sprache nutzen, um damit lesbarer zu sein.

Was ist das Problem, was die Herausforderung?

Es ist deutlich schwieriger, Anforderungen einer Anwendung korrekt aufzunehmen und gute Tests dafür zu schreiben, um die Funktionalität und das Verhalten einer Anwendung zu testen, als das vielfach den Eindruck macht. Insbesondere die Zusammenarbeit mit anderen Stakeholdern, sei es der Kunde oder andere Teams im gleichen Unternehmen, macht die Sache nicht einfacher. Wenn Tests programmiert werden, beispielsweise als klassische Unit-Tests, dann sind diese Beschreibungen ohne zusätzliche Erklärung von außen nicht verständlich.Die Herausforderung, gute Anforderungen zu beschreiben und passende Tests zu definieren, wird dann noch größer, wenn diese verständlich formuliert sein sollen. Hier setzt BDD an und nutzt eine ubiquitäre Sprache, was so viel wie „allgemein verwendete Sprache“ bedeutet. Eine natürliche Sprache mit wenigen dazugemischten Schlüsselwörtern, die auch außerhalb der Entwicklerwelt verständlich ist und die über ein spezielles Tool, zum Beispiel SpecFlow, auf reale Tests beziehungsweise die reale Anwendung gemappt wird.

Was ist SpecFlow?

Entwickelt wird SpecFlow [1] von dem österreichischen Unternehmen Tricentis GmbH. Aus technischer Sicht ist SpecFlow ein Plug-in für Visual Studio oder für JetBrains Rider, bietet aber auch einen Kommandozeilenbefehl und lässt sich somit auch auf einem Build-Server verwenden. In diesem Artikel wird im weiteren Verlauf die Installation und Integration mit JetBrains Rider getestet. Aus organisatorischer beziehungsweise semantischer Sicht ist SpecFlow ein Tool für das automatisierte Testen. Die Idee ist, insbesondere die Spezifikation von Testfällen nicht nur dem Entwicklerteam zu überlassen, sondern auch dem Testteam und dem Product Owner. SpecFlow möchte allen Teammitgliedern Nutzen stiften und die Testautomatisierung als Teamleistung etablieren.Um die Kommunikationslücke zwischen Entwicklern und Domänenexperten zu schließen, kommt die Sprache Gherkin zum Einsatz. Des Weiteren folgen Akzeptanztests in SpecFlow dem BDD-Paradigma. Spezifikationen werden mit Beispielen definiert, sodass sie auch für nicht technische Benutzer leicht verständlich sind. Abnahmetests können dann bei Bedarf automatisch getestet werden, während die Spezifikation als lebende Dokumentation dient.SpecFlow hat zudem eine Reihe von weiteren Produkten unter der sogenannten SpecFlow+-Produktreihe zu bieten. Diese Produkte erweitern SpecFlow um zusätzliche Funktionalitäten. Dazu gehören beispielsweise ein Gherkin-Editor, ein erweitertes Reporting über die lebendigen Dokumentationen (LivingDoc) und vieles mehr.Eine eigene Unterseite auf der Website zeigt die öffentliche Roadmap [2]. Dort ist zu sehen, dass die Verständlichkeit von fehlgeschlagenen Testdurchläufen und das Teilen von Gherkin Features Files auf dem Plan für die nahe Zukunft stehen.Zu SpecFlow gehören verschiedene Komponenten. Kernkomponente ist SpecFlow (Open Source), um Gherkin Feature Files mit den Testfällen zu verknüpfen. Der SpecFlow+ Runner ist Closed Source und bietet zusätzliche Funktionen wie beispielsweise Reports in HTML und JSON an. Diese Komponente ist aber dennoch kostenfrei. Es braucht nur einen Account auf der SpecFlow-Website.SpecFlow+ LivingDoc ist ebenfalls Closed Source. Hinter dem Projekt verbirgt sich eine Reihe von Tools, um die Gherkin Feature Files zu erweitern und in lebendige Dokumentationen zu überführen. LivingDoc teilt sich auf in einen eigenen Generator und eine Azure-DevOps-Komponente.Um alles aus SpecFlow herausholen zu können, müssen die Prinzipien des Behavior Driven Development (BDD) und die Beschreibungssprache Gherkin bekannt sein. Ersteres wird im Kasten Prinzipien von BDD und ATDD kurz angerissen, und zu Gherkin verrät der Artikel im weiteren Verlauf noch weitere Informationen.

Prinzipien von BDD und ATDD

Behavior Driven Development (BDD), also die verhaltensgetriebene Softwareentwicklung, kommt aus der agilen Softwareentwicklung. Verbessert werden soll die Zusammenarbeit zwischen Qualitätsmanagement und Business-Analyse. Bei der Anforderungsanalyse werden dazu die Ziele und Ergebnisse der Software und deren Komponenten in einer bestimmten Textform festgehalten.

Installation

Bild 1 zeigt das Plug-in im Marketplace direkt in JetBrains Rider. Nach der kurzen Installation muss Rider neu gestartet werden. Ein Blick auf die installierten Plug-ins verrät anschließend, dass SpecFlow erfolgreich installiert wurde. Ähnlich verläuft das unter Visual Studio.
Installationdes SpecFlow-Plug-ins unter JetBrains Rider(Bild 1) © Autor
Für diesen Artikel wird JetBrains Rider in Version 2021.1.3 vom 26. Mai 2021 und SpecFlow in der Version 1.6.0 vom 19. April 2021 verwendet.SpecFlow ist ein Open-Source-Projekt. Der Quelltext steht auf GitHub [4] zur Verfügung. Dieses Core-Projekt ist sehr gut gepflegt und steht in Version 3.8.14 zur Verfügung. Viele weitere Informationen werden auf der Website präsentiert. Darüber hinaus gibt es eine sehr umfangreiche Dokumentation unter [5].Momentan werden alle Versionen des .NET Frameworks größer oder gleich 4.6.1 sowie .NET Core unterstützt.

Vorteile von SpecFlow

Entwicklern wird einfacher, modularer und wartbarer Code versprochen. Spezifikationen und die Testautomatisierung werden voneinander getrennt. SpecFlow erreicht das dadurch, dass einzelne Schritte der Spezifikation in eigene Methoden übersetzt werden. Diese Definition von einzelnen Schritten bietet die Verbindung zwischen Feature-Spezifikation in Gherkin und dem entsprechenden API der Anwendung. Die jeweiligen Plug-ins der IDEs erlauben es dann, von den einzelnen Schritten zur Code-Definition zu springen. Das sorgt für eine deutlich vereinfachte Navigation von Spezifikation zu Implementierung. Zudem gibt es noch die Features der Hooks als Event-Bindings, zum Beispiel um zusätzliche Logik auszuführen, sowie die Context-Injektion. Realisiert ist dies über ein eigenes Framework zur Dependency Injection. Dadurch lassen sich Kontext-Klassen in den Testszenarios einbinden und ebenfalls als Shared State realisieren.Für Tester hebt SpecFlow die Unterstützung von BDD hervor, realisiert über die Sprache Gherkin. Darüber lässt sich natürliche Sprache verwenden, um ein Szenario zu beschreiben. Dadurch können sich alle Parteien auf eine nicht technische Sprache einigen, was dem Verständnis zugutekommt. Durch den Einsatz einer eigenen Sprache werden Testszenarien, aufgeteilt nach Features, Szenarios und Testfällen, von der eigentlichen Implementierung getrennt. Das vereinfacht zudem das Reporting, denn Informationen aus den Testdurchläufen werden im Kontext der natürlichsprachigen Spezifikationen visualisiert. Das ist für alle technisch nicht versierten Teammitglieder eine Vereinfachung.Für Product Owner wird das verbesserte Verständnis der Anwendung und deren Testfälle hervorgehoben – ebenfalls über die Features der Sprache Gherkin sowie über die lebendige Dokumentation LivingDoc.Ganz allgemein führt die Diskussion über Testszenarien, die mit Gherkin geschrieben werden, zu einem besseren Verständnis der Anwendung und der Domäne im Team. Im besten Fall lassen sich dadurch die berühmten und berüchtigten Edge-Cases aufspüren.

Erster Einsatz im Projekt

Bevor wir uns um den Einsatz in einem Projekt kümmern, steht die Frage im Raum, was mit SpecFlow überhaupt getestet werden kann.Die Beschreibung des Projekts hat bereits verraten, dass sich Testszenarien beschreiben lassen, die dann über Code mit der Anwendungsschnittstelle verknüpft werden. SpecFlow erlaubt es in diesem Kontext, End-to-End Businessprozesse, Oberflächen von Desktop- und mobilen Anwendungen, APIs, Datenbanken und Weiteres zu testen.Insbesondere der Bereich der API-, Mobile- und Desktop-Test-Automatisierung ist mit SpecFlow sehr gut umzusetzen – zum Beispiel für REST-Services, iOS-, Android-, Windows-Presentation-Foundation-, Windows-Forms- und UWP-Anwendungen.Als Beispiel zu diesem Artikel wird eine einfache Bibliothek mit .NET Core 3.1 erstellt: eine Klasse, die als Taschenrechner fungiert und die die vier Grundrechenarten anbietet. Listing 1 zeigt einen Ausschnitt der Calculator-Klasse im Überblick. Das Projekt wird einmal kompiliert, damit das Build-Erzeugnis vorhanden ist, und um zu testen, dass es keine Fehler gibt.
Listing 1: Ausschnitt aus der Calculator-Klasse
public class Calculator <br/>{ <br/>    public int FirstNumber { get; set; } <br/>    public int SecondNumber { get; set; } <br/><br/>    public int Add() <br/>    { <br/>        throw new NotImplementedException(); <br/>    } <br/>    <br/>    public int Minus() <br/>    { <br/>        throw new NotImplementedException(); <br/>    } <br/>    <br/>    // ... <br/>}  
Im nächsten Schritt geht es jetzt darum, ein SpecFlow-Projekt zu erstellen. Bild 2 zeigt den Dialog in JetBrains Rider, um ein SpecFlow-Projekt zu erstellen. Dieser neue Projekttyp ist durch die Installation des Plug-ins hinzugekommen.
Neues SpecFlow-Projektaus einer Projektvorlage(Bild 2) © Autor
Es gilt als guter Stil, dem Projektnamen den Begriff SpecFlow voranzustellen, gefolgt von der Klasse, und als Endung Specs zu nennen. Denn darum genau geht es: Spezifikationen sollen hinterlegt werden.Die Voreinstellungen können so bleiben. In diesem Fall sind das .NET Core 3.1, xUnit als Test-Framework mit aktiven FluentAssertions. Insbesondere FluentAssertions vereinfacht die Erstellung der Tests ungemein. Im Moment ist es nur möglich, Tests mithilfe von xUnit oder NUnit auszuführen.Ist das Projekt angelegt, sieht die Solution in Rider wie in Bild 3 zu sehen aus. Die Verzeichnisstruktur wird automatisch angelegt und folgt dem SpecFlow-Standard. Es gibt die Verzeichnisse Drivers, Features, Hooks und Steps. In Features befinden sich die Feature Files, die im weiteren Verlauf näher beschrieben werden. Ebenso wie die Step-Definitionen, die sich im Verzeichnis Steps befinden. Im Verzeichnis Drivers sind spezielle Treiber vorhanden, um zum Beispiel Webseiten anzusteuern, und in Hooks sind, wenig verwunderlich, die Hooks abgelegt.
Ein frisches SpecFlow-Projektmit den Standardverzeichnissen(Bild 3) © Autor
Im Anschluss muss das zu testende Projekt, in diesem Fall die Klassenbibliothek, als Referenz zum SpecFlow-Projekt hinzugefügt werden. Das funktioniert ohne große Probleme als Dependency direkt im Projekt. Durch dieses Hinzufügen werden bereits einige Dateien und Konfigurationen im SpecFlow-Projekt erstellt. Das passiert gemäß den öffentlichen Eigenschaften und Methoden, in diesem Fall also FirstNumber, SecondNumber und die Add-Methode.Zu diesem Zeitpunkt lassen sich die Tests der Solution über JetBrains Rider ausführen. Da die Methoden noch nicht implementiert sind, hagelt es verständlicherweise Fehler. Bild 4 zeigt das in einem Screenshot. Es wird dabei auf die Feature-Specs CalculatorFeature.AddTwoNumbers verwiesen, weil dort die Test-Spezifikation definiert ist.
Übersicht der Fehlereines Testdurchlaufs(Bild 4) © Autor

Was ist Gherkin?

Eine Gherkin-Datei wird auch Feature File genannt, weil dort Features mit Szenarien und Testfällen beschrieben sind. Diese Sprache wird in verschiedenen Werkzeugen genutzt, zum Beispiel in Cucumber [6], einem Behavior-Driven-Development-Werkzeug zur textuellen Spezifikation von Anforderungen an Software und zur automatisierten Überprüfung dieser Beschreibung auf ihre korrekte Implementierung.Gherkin ist eine Beschreibungssprache, die auf Basis von natürlicher Sprache die Definition von Testszenarien erlaubt. Zusätzlich existieren in der Sprachdefinition einige Schlüsselwörter, die besonders behandelt werden. Gherkin erlaubt es, verschiedene Ausgangssprachen zu nutzen. Beispielsweise dürfen die Definitionen in Deutsch oder Englisch verfasst sein, was dazu führt, dass auch die Schlüsselwörter in der jeweiligen Sprache zur Verfügung stehen und somit vorbelegt sind. Um die Sprache in der Datei festzulegen, muss zu Beginn des Features # language: de eingetragen werden. Damit werden Schlüsselwörter wie Szenario, Angenommen, Gegeben sei, Wenn, Dann sowie Und vorbelegt und im Text erkannt. In den folgenden Beispielen wird Englisch als Ausgangssprache genutzt.Der Aufbau einer Gherkin-Definition folgt einem strengen Muster und sieht beispielsweise wie folgt aus:
Feature: <Name> 

<Beschreibung> 

@Beispieltag 
Scenario: <Name> 
<Beschreibung> 
Given <Beschreibung> 
And <Beschreibung> 

When <Beschreibung> 
Then <Beschreibung> 
Examples: 
| <Name1> | <Name2> | <NameN> | 

Steps und Binding

Um die konkreten Feature Files für das eigene Projekt zu erstellen, sind die folgenden drei Schritte entscheidend: BDD lernen, die Sprache Gherkin lernen und SpecFlow als Automatisierung nutzen.Wer mit BDD und oder Gherkin noch Probleme hat, wird mit SpecFlow als Tool nicht weit kommen. Ebenso ist es wichtig, BDD als Methode zuvor mindestens im Entwicklerteam zu etablieren, bevor damit aktiv gearbeitet wird.Im SpecFlow-Kontext sind die drei Schritte Discover, Formulate und Automate wichtig.Im ersten Schritt wird gemeinsam an Spezifikationen gearbeitet, im zweiten Schritt diese mit Gherkin beschrieben und anschließend automatisiert.Im nächsten Schritt geht es darum, ein konkretes Feature File zu erstellen und die Gherkin-Definitionen mit dem realen Code zu verknüpfen. Die Schritte in einem Feature File werden Steps genannt. Die Verknüpfungen mit dem realen Code heißen Bindings.Im Verzeichnis Features im generierten SpecFlow-Projekt gibt es die Datei Calculator.feature. Dort werden die Features, Szenarien und einzelnen Schritte definiert.Listing 2 zeigt dazu ein Beispiel. Das Feature heißt Calculator inklusive einer einfachen Beschreibung. SpecFlow erweitert die Gherkin-Sprachdefinition um Markdown. Es lassen sich also auch Hervorhebungen, Links und Bilder einbauen. Dazu später mehr.
Listing 2: Feature File für Calculator-Klasse
Feature: Calculator <br/><br/>Einfacher Taschenrechner, um die **vier <br/>    Grundrechenarten** durchzuführen. <br/><br/>Scenario: Add two numbers <br/>    Given the first number is 10 <br/>    And the second number is 20 <br/>    When the two numbers are added <br/>    Then the result should be 30  
Das Szenario erläutert, wie zwei Zahlen addiert werden. Es wird beschrieben, wie die Eigenschaften der Klasse auszusehen haben, damit bei der Durchführung des When das in Then beschriebene Resultat erzeugt wird.Was jetzt noch fehlt, ist die konkrete Definition, was bei diesen Schritten überhaupt ausgeführt werden soll. Wo werden die übergebenen Daten abgelegt? Welche Methode(n) werden aufgerufen und wo wird das Ergebnis abgelegt?Diese Fragen werden durch die Bindings geklärt. SpecFlow ermöglicht es, zwischen den verschiedenen Definitionen hin- und herzuspringen.Über [STRG]+[F12] lässt sich bei der Markierung des Given-Teils zur Implementierung springen. Geöffnet wird die Datei CalculatorStepDefinitions.cs und zur Methode GivenTheFirstNumberIs navigiert, die genau diesen ersten Schritt abbildet. Damit SpecFlow diese Zuordnung treffen kann, sind einige Auszeichnungen durch Attribute notwendig:
[Binding] 
public sealed class CalculatorStepDefinitions 
[Given("the first number is (.*)")] 
public void GivenTheFirstNumberIs(int number) 
Die Ausschnitte zeigen, welche Attribute genutzt werden, damit die Klasse beziehungsweise die Methoden überhaupt als Binding erkannt werden. Damit realer Code ausgeführt wird, muss der Calculator als Instanz noch eingebaut werden – am besten im Muster der bisherigen Datei:
private readonly Calculator _calculator = 
  new Calculator(); 

_calculator.FirstNumber = number; 
Der erste Teil kommt nach oben in die Klassendefinition, der zweite Teil in die Methode GivenTheFirstNumberIs. Wenn SpecFlow dieses jetzt ausführt, dann übergibt es die Daten einer realen Calculator-Instanz. Bei der Ausführung von Tests wird ein Status ausgegeben, wo die Testausführung hakt. Listing 3 zeigt das vor der Änderung. Beim ersten Schritt, dem GivenTheFirstNumberIs-Methodenaufruf, steht ein pending, da kein realer Code aufgerufen wird und das erzeugte Code-Snippet die Klasse ScenarioContext nutzt. Listing 4 zeigt die Testausführung nach der oben beschriebenen Änderung. Jetzt steht beim ersten Schritt done und beim zweiten Schritt ein pending, weil dieser jetzt mangels realem Code scheitert.
Listing 3: Ausgabe eines fehlerhaften Testdurchlaufs
Given the first number is 10 <br/>-> pending: CalculatorStepDefinitions<br/>  .GivenTheFirstNumberIs(10) <br/>And the second number is 20 <br/>-> skipped because of previous errors <br/>When the two numbers are added <br/>-> skipped because of previous errors <br/>Then the result should be 30 <br/>-> skipped because of previous errors 
Listing 4: Ausgabe bei funktionierendem Schritt
Given the first number is 10 <br/>-> done: CalculatorStepDefinitions<br/>  .GivenTheFirstNumberIs(10) (0,0s) <br/>And the second number is 20 <br/>-> pending: CalculatorStepDefinitions<br/>  .GivenTheSecondNumberIs(20) <br/>When the two numbers are added <br/>-> skipped because of previous errors <br/>Then the result should be 30 <br/>-> skipped because of previous errors  
Nach diesem Prinzip lassen sich nun alle Schritte über Bindings mit realen Methoden verknüpfen. Zu guter Letzt fehlt noch der Vergleich von erwartetem und realem Ergebnis. Über die Erweiterung Fluent Assertions lässt sich das gut realisieren:
[Then("the result should be (.*)")]
public void ThenTheResultShouldBe(int result)
{
result.Should().Be(_result);
}Nach einem erneuten Build-Vorgang und einer erneuten Testausführung ist dann das gesamte Testszenario grün, weil Erwartung und Realität miteinander übereinstimmen. Nicht zu vergessen ist, dass die Methoden im Calculator ebenfalls implementiert werden müssen. Wird diese Änderung vergessen, erinnert die NotImplementedException aber auch daran.Die Bindings in den einzelnen Schritten dürfen auch in F# geschrieben werden, um die Vorteile von F# in der Definition von Tests zu nutzen.

Hooks und das Driver Pattern

Mit Hooks, einem anderen Namen für Event Bindings, lassen sich zusätzliche Methoden mit zusätzlicher Logik ausführen – zum Beispiel, wenn ein Test-Setup vorher initialisiert werden muss. Es gibt dazu eine Reihe von Attributen, um zu spezifizieren, wann eine Methode in einem Hook aufgerufen werden soll. Beispiele für diese Attribute sind die folgenden:
  • [BeforeTestRun] und [AfterTestRun]
  • [BeforeFeature] und [AfterFeature]
  • [BeforeScenario] oder [Before] und [AfterScenario] oder [After]
  • [BeforeScenarioBlock] und [AfterScenarioBlock]
  • [BeforeStep] und [AfterStep]
In den Hooks lässt sich der ScenarioContext [7] nutzen. Entweder über Constructor oder Parameter Injection. Dieser Context kann beispielsweise genutzt werden, um Daten darin abzulegen.Wenn es Hooks mit gleichen Attributen gibt, zum Beispiel zweimal BeforeScenario, dann werden diese Methoden in einer unvorhersehbaren Reihenfolge ausgeführt. Um die Reihenfolge explizit zu definieren, lässt sich der Order-Parameter beim Attribut nutzen: [BeforeScenario(Order = 0)]Das Driver Pattern ist eine zusätzliche Schicht zwischen den Step-Definitionen und dem Code zur Automatisierung. Der Hintergrund ist, dass die Step-Definitionen so kompakt wie möglich gehalten werden sollen. SpecFlow gibt als grobe Richtlinie zehn Codezeilen in einem Step an. Die Initialisierung von anderen Treibern – zum Beispiel Selenium für den Zugriff auf eine Webseite – werden aus diesem Grund ausgelagert. Die Dokumentation zu SpecFlow zeigt dazu ein gutes Beispiel [8] beim Zugriff auf verschiedene Elemente einer Website.

Feature Files

Die Gherkin-Syntax mit den Testfällen und den Given/When/Then-Abschnitten ist eine der am gebräuchlichsten Syntaxen. Auf der einen Seite ist es wichtig, diese Feature Files einfach und übersichtlich zu halten. Auf der anderen Seite ist den Machern von SpecFlow aufgefallen, dass das ein oder andere Feature nicht verkehrt ist, um noch mehr aus den Feature Files herauszuholen. Das dient der besseren Kommunikation zwischen allen Beteiligten, da die zusätzlichen Informationen ein tieferes Verständnis für die Features und Testszenarien vermitteln können.Aus diesem Grund wurde Markdown hinzugefügt – genau genommen zwischen der Definition von Features und des ersten Szenarios – also bei der Beschreibung dieses Features, wenn wir noch einmal Listing 2 betrachten. In diesem Abschnitt ist Markdown mit seinen Hervorhebungen, Links und Bildern einsetzbar. Auch eine Tabellendefinition in Markdown ist möglich, um zum Beispiel Wertebereiche und Wertebeispiele gut lesbar zu gestalten und zu dokumentieren. Pfade zu Bildern können entweder absolut oder relativ sein. Zudem dürfen bei Links externe oder interne Links in demselben Feature File genutzt werden. Ein Feature File darf auch nur die Feature-Definition gefolgt von Markdown enthalten, die Definitionen von Schritten sind nicht zwingend erforderlich. Bild 5 zeigt dazu ein Beispiel.

Lebendige Dokumentationen

Screenshot eines Feature Filesmit ausschließlich Markup als Inhalt(Bild 5) © Autor
Durch diese Markdown-Erweiterungen der Feature Files lassen sich gut Dokumentationen über den Teststand einer Anwendung oder Komponente erstellen. Das sind dann im Grunde nichts anderes als automatisierte und durch die Testdaten validierte Spezifikationen. Wie eine lebendige Dokumentation. Diese lässt sich problemlos mit dem Team teilen.Dieses Feature hat einen eigenen Namen, LivingDoc, und ist eine Erweiterung zu SpecFlow. Erzeugt werden HTML-Dateien, um die Ergebnisse der automatisierten Testläufe außerhalb der IDE und SpecFlow in einem ganz normalen Browser anzuzeigen. In diesen HTML-Dateien sind alle definierten Szenarios enthalten. Somit dient die Dokumentation der Single Source of Truth, denn die Informationen werden bei jedem Build automatisch aktualisiert.Es gibt zwei unterschiedliche Arten, LivingDoc in Betrieb zu nehmen. Einmal als dedizierte Azure-DevOps-Erweiterung. Im anderen Fall lässt sich die LivingDoc-Erweiterung einfach in SpecFlow installieren, um die automatisierte Ausführung in einer CI/CD-Pipeline zu definieren. Lokal lässt sich LivingDoc wie folgt installieren:
dotnet tool install --global SpecFlow.Plus.LivingDoc.CLI 
Nach wenigen Sekunden steht der Befehl livingdoc auf der Kommandozeile zur Verfügung. Um LivingDoc auszuführen, wird zunächst in das SpecFlow-Projekt der Beispielanwendung gewechselt. Dort reicht es dann aus, das folgende Kommando zu starten:
livingdoc test-assembly SpecFlowCalculator.Specs.dll 
  -t TestExecution.json 
Im Zweifel muss der Name der Assembly angepasst werden, wenn die Spezifikationen in einem Projekt mit abweichendem Namen eingetragen wurden. Im gleichen Verzeichnis wird eine Datei Namens LivingDoc.html erzeugt.Darin befindet sich die angesprochene lebendige Dokumentation. Bild 6 zeigt die Übersicht der aktuell vorhandenen Features. Die Markdown-Formatierungen sind ebenso vorhanden wie die Übersicht der durchgeführten Testfälle. Auch das konkrete Szenario mit den Schritten und den übergebenen Daten ist zu sehen. Zusätzlich erlaubt es LivingDoc, die Analyse der Testfälle aufzurufen. Das zeigt Bild 7. Es werden alle Features, Szenarios und Steps aufgelistet sowie die Anzahl dieser Elemente und wie viele davon erfolgreich beziehungsweise nicht erfolgreich abgeschlossen wurden.
Übersicht der Testergebnisseeines Durchlaufs in der lebendigen Dokumentation(Bild 6) © Autor
Übersicht der Analyseergebnisseeines Testdurchlaufs in der lebendigen Dokumentation(Bild 7) © Autor
Beide Übersichten und die einfache Erzeugung der Informationen bieten einen guten Überblick über den aktuellen Testverlauf sowie viele Vorteile in einem Softwareprojekt.

Integration mit anderen Bibliotheken

Neben den bisher vorgestellten Integrationen in IDEs über Plug-ins und der Erweiterung LivingDoc bietet SpecFlow noch weitere Möglichkeiten der Integration an. Ein Beispiel ist Selenium [9]. Das ist ein Open Source Automation Framework, das für das automatisierte Testen von Web-Anwendungen in verschiedenen Browsern und auf verschiedenen Plattformen zum Einsatz kommt. Selenium lässt sich wunderbar einsetzen, um in einer Spezifikation die Bindings zu nutzen, um beispielsweise Elemente einer Website zu finden, um mit diesen zu interagieren. Eine Extraseite in der Dokumentation von SpecFlow erklärt umfangreich, wie das funktioniert und welche Schritte dafür durchzuführen sind. Daher sei an dieser Stelle auf die Dokumentation verwiesen [10].Zusätzlich existiert in der Dokumentation ebenfalls eine Extraseite, auf die hier ebenso aufgrund des Umfangs verwiesen [11] wird, um das Testen von Controllern eines ASP.NET Core MVC Web-Projekts zu zeigen.Dort wird beschrieben, was notwendig ist, um die Controller mit Features Files zu testen. Den Test der Oberfläche übernimmt dann wieder Selenium.Beide Beispiele zeigen, dass sich SpecFlow einsetzen lässt, um verschiedene Anwendungen auf diversen Plattformen zu testen.

Alternativen zu SpecFlow

Das Tool SpecFlow ist nicht das einzige Tool im Bereich Behavior Driven Development und Testing. Als Alternativen für .NET seien Atata, Fixie, LightBDD, NaturalSpec und Randoop.NET genannt – alle mit ihren Vor- und Nachteilen. Nicht alle diese Bibliotheken und Tools können mit SpecFlow konkurrieren. Randoop.NET ist beispielsweise eine Bibliothek, um das API einer Anwendung mit Fuzzy-Methoden zu testen. Es handelt sich also nicht wirklich um ein Tool oder Framework für Akzeptanztests. NaturalSpec kommt dem schon deutlich näher. In F# geschrieben erlaubt es die Definition von testbaren Spezifikationen auf Basis von Definitionen in natürlicher Sprache.Wer einen Blick über den .NET-Tellerrand werfen möchte, findet mit Bibliotheken wie beispielsweise Cucumber und JBehave Alternativen im Java-Ökosystem. Unter Python ist Lettuce ziemlich bekannt und für JavaScript existiert zum Beispiel Jasmine. Das zeigt, dass es zahlreiche andere Beispiele beziehungsweise Alternativen gibt. BDD ist mittlerweile recht stark verbreitet und findet immer mehr Anhänger, sodass auch die Toolauswahl umfangreicher wird.

Fazit

SpecFlow ist ein sehr intuitives Tool, das sich einfach in den Softwareentwicklungsprozess integrieren lässt, zumindest was das Plug-in und die weitere Arbeit damit anbelangt.Das Thema BDD und die Art und Weise, wie Testszenarien formuliert und Tests durchgeführt werden, muss natürlich im Team beziehungsweise Unternehmen definiert und etabliert sein. Da kann SpecFlow nur bedingt helfen.Es steht aber zumindest nicht im Weg, sondern erlaubt es, den Prozess des Behavior Driven Developments sehr gut umzusetzen.Die vielen Erweiterungen – unter anderem sei hier das Feature LivingDoc genannt – sorgen dafür, dass es zahlreiche Anwendungsszenarien gibt und SpecFlow sich vollumfänglich in den Prozess der Softwareentwicklung einbinden lässt.Zudem ist es Open Source und kostenfrei, bietet aber im Hintergrund dennoch zahlreiche Hilfestellungen, zum Beispiel in Form einer umfangreichen Dokumentation oder über Trainings.Alles in allem ist ein Blick auf SpecFlow zu empfehlen, wenn BDD schon zum Einsatz kommt oder in Erwägung gezogen wird. Das Tool verdient sich eine klare Empfehlung und das Gesamturteil „sehr gut“.
Projektdateien herunterladen

Fussnoten

  1. Die Website von SpecFlow, https://specflow.org
  2. Die Roadmap zu SpecFlow, http://www.dotnetpro.de/SL2108Frameworks1
  3. Fabian Deitelhoff, Dokumentieren und testen, dotnetpro 7/2021, Seite 98 ff., http://www.dotnetpro.de/A2107Frameworks
  4. Das Git Repository zu SpecFlow auf GitHub, http://www.dotnetpro.de/SL2108Frameworks2
  5. Die gute Dokumentation zu SpecFlow, http://www.dotnetpro.de/SL2108Frameworks3
  6. Die Website zu Cucumber, https://cucumber.io
  7. Die Dokumentation zu SpecFlow über den ScenarioContext, http://www.dotnetpro.de/SL2108Frameworks4
  8. Die Dokumentation zu SpecFlow über das Driver-Pattern, http://www.dotnetpro.de/SL2108Frameworks5
  9. Die Website zu Selenium, https://www.selenium.dev
  10. Die Dokumentation zu SpecFlow über das Testen von Websites mit Selenium, http://www.dotnetpro.de/SL2108Frameworks6
  11. Die Dokumentation zu SpecFlow zum Testen von ASP.NET Core MVC Controllern, http://www.dotnetpro.de/SL2108Frameworks7

Neueste Beiträge

DWX hakt nach: Wie stellt man Daten besonders lesbar dar?
Dass das Design von Websites maßgeblich für die Lesbarkeit der Inhalte verantwortlich ist, ist klar. Das gleiche gilt aber auch für die Aufbereitung von Daten für Berichte. Worauf besonders zu achten ist, erklären Dr. Ina Humpert und Dr. Julia Norget.
3 Minuten
27. Jun 2025
DWX hakt nach: Wie gestaltet man intuitive User Experiences?
DWX hakt nach: Wie gestaltet man intuitive User Experiences? Intuitive Bedienbarkeit klingt gut – doch wie gelingt sie in der Praxis? UX-Expertin Vicky Pirker verrät auf der Developer Week, worauf es wirklich ankommt. Hier gibt sie vorab einen Einblick in ihre Session.
4 Minuten
27. Jun 2025
„Sieh die KI als Juniorentwickler“
CTO Christian Weyer fühlt sich jung wie schon lange nicht mehr. Woran das liegt und warum er keine Angst um seinen Job hat, erzählt er im dotnetpro-Interview.
15 Minuten
27. Jun 2025
Miscellaneous

Das könnte Dich auch interessieren

UIs für Linux - Bedienoberflächen entwickeln mithilfe von C#, .NET und Avalonia
Es gibt viele UI-Frameworks für .NET, doch nur sehr wenige davon unterstützen Linux. Avalonia schafft als etabliertes Open-Source-Projekt Abhilfe.
16 Minuten
16. Jun 2025
Mythos Motivation - Teamentwicklung
Entwickler bringen Arbeitsfreude und Engagement meist schon von Haus aus mit. Diesen inneren Antrieb zu erhalten sollte für Führungskräfte im Fokus stehen.
13 Minuten
19. Jan 2017
Evolutionäres Prototyping von Business-Apps - Low Code/No Code und KI mit Power Apps
Microsoft baut Power Apps zunehmend mit Features aus, um die Low-Code-/No-Code-Welt mit der KI und der professionellen Programmierung zu verbinden.
19 Minuten
Anzeige
Anzeige
Anzeige
Anzeige
Anzeige