•
20 October 2020
•
8 mins
Dit is het derde artikel in de ‘Dear non-IT people’ reeks waarin ik IT begrippen probeer te versimpelen voor niet ICT ers:
Waarom hebben ze het nu al weken over Trunk based development?
Over pipelines en continuous van alles en nog wat.
IT is voor ‘buitenstaanders’ vaak een black box met zijn eigen vakjargon, heel veel afkortingen en vaak zelfs een eigen cultuur. Zaken klinken vaak heel complex en er duiken regelmatig nieuwe buzzwords op met een nieuwe belofte van snelheid, kostenbesparing en toekomstvastheid. Helaas zie je die zaken vanuit de business niet altijd terug.
Toch zul je verrast zijn over hoe relatief simpel veel IT zaken kunnen zijn. Of beter: zouden moeten zijn. In een aantal korte blogpost zal ik proberen om een aantal van de laatste buzzwords en begrippen uit te leggen zodat ze begrijpbaar zijn en zodat jij vooral beter kan aanvoelen of er effort wordt gestoken in de juiste zaken op het juiste moment.
In dit artikel vertelde ik iets meer over automatisch testen, een erg belangrijk onderdeel van continuous integration. Ik leg begrippen als unit testing, integratie testen, end to end testing, acceptatie testen, TDD, BDD, code coverage uit
Er was een tijd dat software development een zeer strak gedefinieerde fasering had waarbij testen de laatste stap was. Als er nog budget over was dan. In de praktijk werd dat vaak een ellenlange ‘it’s not a bug, it’s a feature’ discussie. Tegenwoordig hebben we meer de neiging om testen als integraal onderdeel van software ontwikkeling te zien en niet een afgebakend onderwerp. Ook het automatisch testen is tegenwoordig ook een geaccepteerde en standaard manier van werken.
Continuous delivery zonder testen is een beetje als je airbags uitzetten en met een blinddoek de A4 oprijden. Je ziet wel hoe het gaat en misschien kom je best een eind maar of het nou een goed plan is… Ik kan me voor beide dan ook geen goede argumenten bedenken.
Als voorbeeld voor dit artikel nemen we een shopping card van een webshop:

In principe kijken we hier al naar minimaal 4 features (waarbij ik de footer even buiten beschouwing laat) die elk weer hun eigen functionaliteiten hebben. Alle functionaliteit samen resulteert erin dat een klant zijn of haar order kan opmaken en in een volgende stap iets kan bestellen:


Elke feature of component heeft zijn eigen specifieke set aan functies. Bijvoorbeeld het optellen als je op het plusje naast de schoen klikt of het invullen en controleren van een coupon code. Het testen van al deze functies noemen we unit testen. Een unit doet idealiter maar één ding. Laten we de berekeningen van de item prijs als voorbeeld nemen:

De eerste regel geeft de totaalprijs aan en de code hiervoor zal dus iets zijn als:
Totaalprijs items = item prijs x aantal. In dit geval dus 1 x 299,43.
Een unit test is een stukje code wat elke keer als de testen worden gedraaid controleert of de code nog doet wat ie moet doen. In dit geval zou de test er als volgt uitzien:
In dit voorbeeld betaal je alleen verzendkosten als je onder de $300 aan items besteld. De unit testen hiervoor zijn:
(de totaalprijs van de items is dus $ 150,-. Dit is lager dan $ 300 en dus moeten er verzendkosten worden betaald)
Hetzelfde doen we ook voor de importkosten en het totaal van de card. Het is erg fijn om te weten dat wat we ook veranderen in de code dat de berekeningen in ieder geval juist zullen zijn.
TDD staat voor Test Driven Development. Het is een manier van werken waarbij je eerst de test schrijft en pas daarna de code. Om de test in eerste instantie te kunnen schrijven moet een ontwikkelaar erg goed begrijpen wat de functionaliteit moet doen.
De zin: stel de item prijs is $ 50 en het aantal 3 dan is de verwachte totaalprijs van alle items $150,- geeft een bredere context en een voorbeeld over wat er daadwerkelijk moet gebeuren. Het maken van de functionaliteit is een kwestie van deze test te laten slagen.

Met integratie testen bekijken we of de samenwerking tussen de features/componenten ook goed werken. We moeten bijvoorbeeld zeker weten dat we het totaalbedrag goed doorgeven aan de creditcard provider. Maar ook de samenwerking tussen de verschillende onderdelen binnen een feature moeten we goed testen. Je kunt het vergelijken met een zin. Elk woord is goed gespeld, maar je zult toch moeten kijken of het geheel (de zin) ook goed is.
Als we op het plusje naast de schoen klikken dan verwachten we dat de prijzen ook worden aangepast. We testen in dit geval of we de juiste aantallen doorkrijgen en niet of het plusje werkt. De werking van het plusje hebben we immers al als unit test gedekt (elke klik op het plusje hoogt het aantal op met één).

Deze testen hebben het meeste raakvlak met hoe de gebruiker de software ervaart. We bekijken hier het gedrag van de applicatie. Ook de beschrijvingen van deze testen worden vaak in menselijke taal geschreven.

BDD staat voor Behaviour Driven Development en ATDD voor Acceptance Test Driven Development en is dus hetzelfde als automatische acceptatie testen. End-to-end betekent dat we de applicatie van begin tot het einde testen.
In al deze gevallen betekent dit dat we vooraf het gewenste gedrag al kunnen beschrijven en de validatie hiervan automatiseren als onderdeel van het ontwikkelproces.
Het mooie hiervan is dat personen van elke discipline hierover kunnen meedenken en stappen kunnen beschrijven. Het is heel verhelderend om vooraf al te bedenken welke stappen een user neemt (een user journey) en wat voor keuzes we vooraf al kunnen maken. Het beste is om te starten met een happy path (de ideale user journey zonder complicaties) en daarop varianten verzinnen:

De test om de coupon functionaliteit te testen:
En in het geval van een juiste code:
Misschien heb je je team wel eens over Cucumber horen praten en dacht je dat dat wel vreemd was aangezien het nog lang geen lunchtijd was. Cucumber is simpelweg een tool die al een tijd bestaat waarmee je BDD & ATDD testen kan doen. Hoewel Cucumber erg bekend is zijn er de afgelopen jaren enorm veel automatische test tools bijgekomen.
De code coverage is het aantal relevante regels code wat wordt getest. Vaak wordt er een getal als 80% aangehouden maar er zijn ook zat teams die de coverage rond de 100% willen houden. Op het moment dat deze coverage te laag wordt kan je ervoor zorgen dat de pipeline stopt. Coverage zegt echter niks over de kwaliteit van de testen! Je kunt namelijk ook weer slechte automatische testen schrijven. Iets wat hierbij dan weer kan helpen (testen voor je testen) zijn mutation tests maar dat gaat te ver voor dit artikel.

Hoewel er altijd in elke applicatie, en vaak op het meest onmogelijke momenten, bugs kunnen optreden hebben we door het automatiseren het moment van testen naar voren getrokken en testen we vele malen vaker. De automatische testen worden continu door de ontwikkelaars gedaan, bij elke commit op de test- en productie servers.
In het kort levert automatisch testen de volgende voordelen:
Heb je nog vragen/aanvullingen? Hoor je vaak argumenten waarom jullie applicatie/programmeertaal/bedrijf niet geschikt is om te testen? Laat een reactie achter. Dan kijken we er samen eens naar.
Like it? Share it!