Technology

Gherkin: hoe een augurk helpt om leesbare testen te schrijven

By 22 maart 2018 maart 13th, 2019 No Comments
Blog: Gherkin

Hoe kan je Gherkin en SpecFlow gebruiken om leesbare en onderhoudbare testen te schrijven?
De inhoud van deze blog is gericht op developers. Wil je als analist weten hoe Gherkin kan helpen om de communicatie rond acceptatiecriteria en geautomatiseerd testen te verbeteren? Lees dan zeker dit artikel: Gherkin for Business Analysts.

Probleem

Binnen Elvive kan de setup die nodig is om een test uit te voeren behoorlijk uitgebreid zijn. Om een eenvoudige test case te behandelen, zoals het controleren of een overuur werd toegekend, moet volgende setup worden uitgevoerd:

  • Maak werkgever Prato aan
  • Maak werknemer Stijn aan
  • Maak contract Prato-Stijn op 1/10/2017 aan met uurrooster 8-8-8-8-6-0-0
  • Registreer 8 uren werkelijke arbeid op 16/10/2017
  • Registreer 8 uren werkelijke arbeid op 17/10/2017
  • Registreer 8 uren werkelijke arbeid op 18/10/2017
  • Registreer 8 uren werkelijke arbeid op 19/10/2017
  • Registreer 8 uren werkelijke arbeid op 20/10/2017

Daarna moet een service worden aangeroepen die bovenstaande setup gebruikt om tot arbeidstijd te komen. Als laatste voeren we een aantal controles uit om het resultaat te valideren.

Hoe beschrijven we dit alles in een test fixture op een duidelijke, eenvoudige manier?

Oplossing

Gelukkig bestaat er een methode om bovenstaande test te beschrijven: Behavior Driven Development (BDD). De term BDD werd lang geleden geïntroduceerd door Dan North en heeft in de loop der jaren behoorlijk wat aan populariteit gewonnen.

Het idee achter BDD blinkt dan ook uit in zijn eenvoud. 3 eenvoudige zinsconstructies helpen om meer structuur te brengen in een test case:

Gegeven ..
Als …
Dan …

Deze zinsconstructies werden later zelfs geformaliseerd in een domain specific language (DSL): Gherkin, vandaag de augurk 🙂

Laten we even teruggaan naar onze voorbeeldcase. Hoe zouden we deze vormgeven binnen BDD?

In de Gegeven … zinsconstructie bouwen we de context van onze test op. In het eerder aangehaalde voorbeeld zou dit resulteren in volgend fragment:

Gegeven een contract StijnPrato tussen Prato en Stijn op 1/10/2017
En het contract StijnPrato heeft een uurrooster 8-8-8-8-6-0-0
En ik heb op 16/10/2017 8 uren werkelijke arbeid voor contract StijnPrato
En ik heb op 17/10/2017 8 uren werkelijke arbeid voor contract StijnPrato
En ik heb op 18/10/2017 8 uren werkelijke arbeid voor contract StijnPrato
En ik heb op 19/10/2017 8 uren werkelijke arbeid voor contract StijnPrato
En ik heb op 20/10/2017 8 uren werkelijke arbeid voor contract StijnPrato

De Als … zinsconstructie beschrijft de actie die wordt uitgevoerd:

Als ik arbeidstijd ga interpreteren voor contract StijnPrato

De Dan … zinsconstructie omschrijft hoe de uitkomst moet worden gevalideerd.

Dan verwacht ik een totaal van 40 geïnterpreteerde uren
Dan verwacht ik 38 uren normale werkelijke arbeid
Dan verwacht ik enkel op 20/10/2017 2 uren overuren

Ok, we kunnen nu onze test omschrijven met volzinnen. Maar hoe vertalen we dit in uitvoerbare testen? Voor .NET bestaat er een officiële tool die gebaseerd is op de Gherkin DSL: SpecFlow. Met SpecFlow kunnen we bovenstaande zinsconstructies gebruiken om testcode te schrijven die door nUnit kan worden uitgevoerd.

Een nieuwe test toevoegen d.m.v. SpecFlow is eenvoudig. We beginnen met het toevoegen van een .feature bestand. Voor ons voorbeeld zou dit betekenen dat we een Overuren.feature bestand aanmaken met volgende inhoud:

Gherkin - Voorbeeld feature betand

Daarna laten we SpecFlow de code genereren voor elk van de zinnen die we in het feature bestand hebben geschreven. SpecFlow is slim genoeg om onze variabelen te detecteren (in het lichtgrijs) en code te genereren die herbruikbaarheid toelaat. Voor de zin ‘En ik heb op 16/10/2017 8 uren WerkelijkeArbeid voor contract StijnPrato’ resulteert dit in volgende methode:

Gherkin - SpecFlow stap

Als we in een latere test ook arbeidsgegevens willen toevoegen voor een bepaalde dag en een bepaald contract kunnen we de zin dus gewoon hergebruiken en moet er geen code meer gegenereerd worden. SpecFlow kan de zin automatisch mappen op onze eerder gegenereerde stap.

Bij het uitvoeren van de test zie je voor elke stap in de test of hij al dan niet gelukt is:

Gherkin - Test resultaat

Hoe krijgen we een duidelijk overzicht dat ook door analisten kan worden gebruikt?

Onze enige bedenking bij SpecFlow is dat de IDE integratie nog niet op punt staat. Zo kan de visualisatie in het Unit Test Sessions venster in Visual Studio nog heel wat beter en komen we soms wel enkele quirks tegen. Hopelijk worden hier nog verbeteringen in aangebracht in volgende versies. Er bestaat wel een SpecFlow+ versie waarin de test visualisatie wel overzichtelijk is. Maar helaas is deze betalend en aan de dure kant 🙁

Een van de volgende stappen zal alvast zijn om de SpecFlow output te visualiseren in TeamCity. Hieronder alvast een voorbeeld van hoe dit er zal uitzien:

Gherkin - specflow-teamcity

Moeten we alle testen nu schrijven in Gherkin/SpecFlow?

Uiteraard niet. BDD en Gherkin blinken uit in het schrijven van testen zoals het voorbeeld dat we in deze post hebben aangehaald. Maar soms zijn SpecFlow en Gherkin ook gewoon overkill. Je kan BDD ook toepassen door de gegeven – als – dan constructie te gebruiken in class names en method names.

Gherkin en SpecFlow zijn oplossingen voor een heel specifiek probleem. Maar een andere testaanpak of schrijfwijze kan beter geschikt zijn voor een andere test case. Zoals steeds in software geldt weer: There is no silver bullet.