2 1 3

Unit test structuring

Florian van der Wielen, Front-end developer

Wat is testen, waarom testen we, hoe testen we, wanneer testen we?

Testen is controleren of bepaalde condities correct zijn. Als developers bouwen wij applicaties. We bouwen deze applicaties met de hoop dat ze nuttig of productief zijn. Met andere woorden, we willen vertrouwen hebben in de applicaties die we bouwen, dat die zich op productie zo gedragen als we verwachten. Dat vertrouwen bouwen we op door gebruik van de applicatie te simuleren en te controleren of de applicatie zich zo gedraagt als we verwachten.  Door deze simulatie zo gelijk mogelijk te houden aan productie verwachten we dat als de applicatie daar alle tests doorstaat dat het ook in productie werkt.

We kunnen dit met de hand doen, maar dit is foutgevoelig, langzaam en duur.  Zeker kleine brokjes code in laag gelegen stukken van een programma lenen zich goed voor geautomatiseerde tests.  Een groot voordeel is dan ook dat we de tests herhaaldelijk kunnen uitvoeren zonder dat er mensen aan te pas moeten komen, die fouten kunnen maken.  Als de tests succesvol zijn dan hebben we een test applicatie gebouwd die ons garandeert dat het werkt. Zo kunnen we spreken van een programma dat test (het test programma) en een programma onder test (Program under test).

Hoare triples en Gherkins

Een testprogramma maken is is eigenlijk onze verwachtingen van de applicatie modelleren. We verwachten dat de applicatie op een bepaalde manier werkt die nuttig is voor de gebruiker, of voor een ander stuk van de applicatie. Er zijn twee technieken hoe je dit modelleren kan doen, die meer of minder komen tot dezelfde principes.

De eerste die ikzelf geleerd heb heet de “Hoare triple”. Dit is een redeneringssysteem dat gebruikt wordt om applicaties en hun gedrag te bewijzen. De beredenering is dat als de applicatie zich in een bepaalde toestand begeeft op een bepaalde regel code, dat het zich ook bevindt in een bepaalde toestand op de regel daarvoor of daarna die daaraan gerelateerd is. Voor elke soort regel code zijn er verschillende regels in hoe dit de toestand verandert van de regel die ervoor staat of erna komt. Het klinkt allemaal redelijk vaag maar het voorbeeld hieronder geeft meer duidelijkheid:

Als we in de code weten dat bij punt P de waarde van Y gelijk is aan 1 dan weten we dat bij punt Q de waarde van x ook gelijk is aan 1. Dit idee, met een toestand P, een coderegel en dan een toestand Q, heet een Hoare triple [1]. Dat is dus zo’n beredeneringsregel en zulk soort regels zijn er voor alle soorten code te bedenken. Met deze regels kunnen we dus onze hele applicatie doorberedeneren en als die redeneringen overeen komen met onze verwachtingen dan zijn we tevreden. Om dit handmatig te doen of te automatiseren is helaas enorm arbeidsintensief en dit is dus ook niet hoe we het gaan aanpakken.

In het Cucumber test framework hebben ze een soortgelijke redenering over hoe tests geschreven kunnen worden. Dit noemen ze daar een Gherkin (augurk):

-        Gegeven een bepaalde situatie die ik wil testen (aangezien het een situatie is die waarde toevoegd aan mijn applicatie)

-        Als ik de applicatie op een bepaalde manier gebruik

-        Dan zou de applicatie volgens verwachting moeten reageren

Het patroon komt erg overeen met de “Hoare triple”, maar in plaats van zelf te redeneren en zo aan onze verwachtingen te voldoen, bouwen we een test applicatie die automatisch de verwachtingen voor ons controleert op een globaler niveau dan regel voor regel.

Ik kan sterk aanraden om de testers in je team te vragen hoe zij dit aanpakken. Zij hebben vaak bepaalde inzichten op wat we wel en niet testen in verschillende lagen van je applicatie. Je kan van je tester een hoop leren over hoe je kwalitatieve applicaties bouwt en je deelt ook kennis binnen je

Code als documentatie met behulp van Jasmine

We begrijpen nu hoe je met behulp van Gherkin individuele tests kan schrijven. Het is ook handig om je tests te kunnen groeperen. Normaal gesproken schrijf je code die werkt in veel verschillende situaties. Dus schrijven we veel tests om al deze situaties te checken. Deze tests geven ons meer dan alleen het vertrouwen om onze applicatie in productie te zetten. Omdat deze tests beschrijven hoe al onze code componenten zich gedragen in een bepaalde situatie, is dit zeer geschikte documentatie over hoe onze componenten werken. Dat is ook het leuke aan het Jasmine test framework. Het zorgt ervoor dat je de structuur van je tests zo bouwt en groepeert dat het documentatie genereert op het moment van uitvoeren. Bijvoorbeeld:


Unit test structuring code 2

Let op dat alle test code is verwijderd om dit voorbeeld leesbaar te houden. De echte code is gestructureerd naar het Gherkins principe met regels code voor gegeven, als en dan. Dit genereert de volgende output als je de tests draait:

Unit test structuring code 3

Het geeft dus meteen een opsomming van de werking van de component en groepeert dit precies zoals je het zelf indeelt.

Er zijn nog meer stappen mogelijk voor unit testen. Je zou de tests kunnen toevoegen aan een geautomatiseerde build en CICD straat. Je kan Test Driven Development toepassen voor het beter werken met kleine componenten. Dit artikel is daarentegen al lang genoeg! Wellicht in een volgende blog dat ik jullie daar iets meer over vertel. Heb je vragen of wil je laten weten wat je van de blog vond, stuur dan een berichtje via mijn LinkedIn profiel.