Geautomatiseerd testen in Agile; een stappenplan

Traditionele succesfactoren voor testautomatisering worden in Agile omgevingen steeds vaker ingehaald door de realiteit. Waar we als test-professionals voorheen vooral waakzaam moesten zijn op factoren als: “Is het systeem voldoende stabiel om testen te kunnen automatiseren?”, “Is ons testproces voldoende volwassen om geautomatiseerd testen rendabel te kunnen maken?” of “Ga ik mijn testen wel voldoende vaak herhalen om de investering van geautomatiseerd testen terug te verdienen?”, is testautomatisering in Agile softwareontwikkeling vanaf het allereerste begin noodzaak.

Vanaf het begin van het project wordt immers al werkende software opgeleverd en de functionaliteit wordt met elke user story uitgebreid. Elke user story heeft daarmee het potentieel om functionaliteit uit vorige user stories te breken, terwijl vooraf niet alle requirements of specificaties voldoende zijn uitgewerkt om een testset over de hele breedte van je applicatie te kunnen plannen. Het belang van een complete regressietestset die op elk gewenst moment, of beter nog, bij elke build kan worden uitgevoerd is levensgroot.
pro-regressie

Begin je in een dergelijk ontwikkeltraject pas met automatiseren als de software het predicaat ‘stabiel’ heeft gekregen of als het testproces aan alle kanten is afgekaderd, dan kijk je tegen een achterstand (technical debt) aan die in de beschikbare tijd niet meer in te halen valt. Bovendien loop je dan het risico te maken te krijgen met een product waarvan je de kwaliteit maar moeilijk kunt aantonen.

Direct beginnen met automatiseren dus. Maar hoe te beginnen? De eerder genoemde succesfactoren voor testautomatisering (zoals: stabiele software, volwassen proces, return on investment) zijn niet uit de lucht gegrepen. Deze factoren hebben in de praktijk hun waarde ruimschoots bewezen; hiervan zijn legio voorbeelden in de vorm van mislukte testautomatiseringsprojecten. Hoe zorg je er nu voor dat jouw geautomatiseerde testset onderhoudbaar wordt, bruikbaar blijft en vooral waarde levert aan het project?

Om te helpen met het bereiken van bovenstaande hieronder een stappenplan uit de praktijk:

1- Denk vooraf na over wat je waar, wanneer en op welke manier (hoe) gaat testen
Dat betekent niet dat je in elke sprint een systeemtest, integratietest, functionele acceptatietest en gebruikersacceptatietest moet inplannen. Het betekent wel dat je vooraf moet bedenken op welke manier je welk type requirement of risico wilt raken in je testen. Voor de testen die uiteindelijk geautomatiseerd moeten worden is het belangrijk om de juiste tool(s) te kiezen voor de testen die moeten worden uitgevoerd. In veel projecten wordt helaas nog altijd naar testtools gekeken als oplossing voor één afgebakend probleem: namelijk testen automatiseren. Helaas zijn er maar weinig testtools geschikt voor alle testen die je in je project wil automatiseren. Een test tool die gebruikersgedrag simuleert op de front-end van je applicatie is minder geschikt voor het controleren van business logica of de verwerking van berichtenverkeer. Een test tool bedoeld voor web-services is niet geschikt voor front-end testen. Vaak bestaat het werk van de tester uit meer dan één van de genoemde voorbeelden. Bedenk daarom vooraf welke testen je wanneer wilt automatiseren en stem, in overleg met het team, de keuze voor de testtools daarop af. Houd rekening met beleid binnen de organisatie, het budget, maar vooral ook met aanwezige kennis en kunde. Kies geen test tool waar je alle testen in een programmeertaal moet uitschrijven als je daar als team niet mee uit de voeten kunt.

2- Zet je testtools in de steigers.
Je project gaat van start, je zit in de planning sessie van sprint 1. Typische stories in de eerste sprint: Inrichten ontwikkelomgeving, Inrichten test- en acceptatieomgeving, Stubs en Drivers. Aan alle kanten worden voorbereidingen getroffen voor een geslaagd stuk software. Het neerzetten van kaders voor geautomatiseerd testen hoort daar ook bij. Maak er dan ook een userstory van en schat de complexiteit van deze user story met het hele team in. In zo’n user story kun je denken aan taken als het bepalen van gebruikte tools, afstemmen van naamgevingsconventies die voor geautomatiseerd testen van belang zijn of het bouwen van een proof-of-concept adapter die werkt met je geselecteerde test tool of -framework. Het is geen schande om als tester hierbij de hulp en expertise van ontwikkelaars in te roepen. Sterker nog; de meeste ontwikkelaars zullen blij zijn dat de tester in het team aangeeft wat hij/zij nodig heeft om goed geautomatiseerd te kunnen testen. Overleg de mogelijkheden om geautomatiseerde systeem- en integratietesten op gezette momenten te gaan laten uitvoeren. Dit zorgt ervoor dat je geautomatiseerde testen een plek krijgen in het realisatieproces. Daarmee worden geslaagde testen een teamverantwoordelijkheid, in plaats van het ‘probleem’ van de tester. Gebruikt je team een systeem voor versiebeheer, dan horen ook de testgevallen in dat systeem beheerd te worden.
testautomation

3- Begin klein (en vaak handmatig).
Alle voorbereidingen en goede intenties ten spijt, blijft testen gewoon mensenwerk. Meer nog; testen is een specialistisch vak en om geautomatiseerd te kunnen testen moet je weten hoe je applicatie werkt en wat je er van mag verwachten, maar zul je vanuit je testexpertise ook moeten bepalen waar je begint met testen (prioriteit), waarom (risico), hoe veel (dekking) en hoe diep (diepgang). Dit is mensenwerk, hier heb je geen tools voor. Zorg dat er voordat die eerste userstory richting testomgeving gaat iets te testen valt. Zorg voor een eerste geautomatiseerde test die, idealiter, kan fungeren als smoke-test voor een omgeving of sanity-check voor een stukje applicatielogica. Probeer in de eerste sprint niet meteen alles te automatiseren, maar gebruik je handmatige testsessies of testgevallen om, behalve vast te stellen dat het gerealiseerde ook het juiste is, ook om te leren hoe de applicatie werkt; gevoel te krijgen voor de onhebbelijkheden van de applicatie of de omgeving en vast te stellen welke testsituaties veel zullen voorkomen of in een regressieset terecht moeten komen. Automatiseer die gevallen dan ook direct. Andere gevallen die je ook zoveel mogelijk direct automatiseert, zijn die gevallen die een bug hebben blootgelegd.

4- Verdeel je testset in logische blokken.
Na de ervaring met een paar eerste stories binnen de applicatie heb je een kleine, maar doordachte set geautomatiseerde testen weten te bewerkstelligen. Afhankelijk van het soort applicatie misschien zelfs meer dan één set. Breid je testsets in elke story uit, maar kijk tegelijkertijd naar de samenhang van je testset en let op onderlinge overeenkomsten of afhankelijkheden tussen testgevallen. Muteert testgeval 2 een record dat in testgeval 1 is aangemaakt? Houd er dan rekening mee dat testgeval 2 niet kan worden uitgevoerd als testgeval 1 mislukt. Vooral wanneer je test op de gebruikersinterface is het van groot belang om nooit op meerdere plaatsen dezelfde handelingen te automatiseren. Maak van een veel voorkomende handeling een herbruikbaar component (modulaire opbouw) en groepeer die scenario’s op een logische manier. Wijzigt er iets aan de applicatie op een veelvoorkomende plek, dan wil je die wijziging het liefst slechts op één plaats hoeven door te voeren. Het is een goed idee om je componenten op dezelfde manier te structureren als de ontwikkelaar de applicatielogica structureert.

5- Laat je testset voor je werken (Continu Testen).
Je geautomatiseerde testen zijn nu goed bruikbaar en leveren waarde aan het project. Regressie-issues worden snel gevonden en omdat veel van de gescripte testen geautomatiseerd worden uitgevoerd heb je meer tijd om de applicatie, vanuit je expertise als tester, handmatig aan de tand te voelen; dit komt de gebruiksvriendelijkheid en robuustheid van de uiteindelijke applicatie ten goede. Nu is het tijd om de geautomatiseerde testen dan ook echt voor het team te gaan laten werken. Richt samen met je team de build- en testomgevingen zodanig in dat je testsets meedraaien in het oplever-proces. Je regressietest en eventuele systeemtesten voor nieuwe requirements zijn nu al uitgevoerd vóórdat de software op de testomgeving terecht komt. Test gefaald? Eerst bevindingen oplossen, dan weer opnieuw proberen. Naast het voordeel van vroeg uitvoeren van testen, is dit dé manier om de zichtbaarheid van je testen te waarborgen. Laat dit ook zien in productdemo’s! Als de product-owner en de ontwikkelaars keer op keer de testen zien werken en het juiste inzicht krijgen in de kwaliteit en de staat van het opgeleverde product, zal het vertrouwen in het product en de kwaliteit van het eigen werk toenemen. Dit zie je uiteindelijk terug in een meer gemotiveerd ontwikkelteam en een hogere velocity.

6- Blijf bij en weeg af.
In de praktijk is het bijna nooit haalbaar (of wenselijk) om al je testen te automatiseren. Er wordt, mede dankzij je betrouwbare testset(s), in een steeds hoger tempo functionaliteit gerealiseerd en het team verwacht van de tester dat de testgevallen continue zijn bijgewerkt. Houd in de planning sessies rekening met de inspanningen voor test. Een story die weinig complex is om te realiseren, kan een grote impact hebben op het onderhoud van je regressietestset of lastig automatiseerbaar zijn vanwege benodigde data of systeemcondities. Weeg steeds af welke testgevallen voor automatisering in aanmerking komen en welke niet en weeg steeds af welk testgeval je waar en wanneer automatiseert.

Tenslotte.
Is testen in een Agile team nu zo anders dan in een waterval-traject? Het antwoord is wat mij betreft ‘nee’. Testen is ook in een Agile team ‘Een verzameling activiteiten die uitgevoerd wordt om een of meer kenmerken van een product, proces of dienst vast te stellen volgens een gespecificeerde procedure.’ (ISO/IEC 1991).
De procedure is alleen een beetje veranderd; We hebben als testers niet meer de ‘luxe’ (en de stress) van een eigen project-in-een-project, waarin we ons eerst bezig houden met reviewen, dan met specificeren en vervolgens met het uitvoeren van testen. We hebben niet meer vooraf een complete set van specificaties van het hele systeem, maar wel steeds van een klein gedeelte daarvan; de userstory. De truc is om als tester om te kunnen gaan met het werken aan hele kleine onderdelen, waarbij de uitdaging is om het grote plaatje nooit uit het oog te verliezen. Er wordt weleens beweerd dat uiteindelijk geautomatiseerde testen de tester overbodig zullen maken, maar de rol van de tester is in de praktijk juist groter aan het worden. Door de continue betrokkenheid en de nauwere samenwerking met zowel de ontwikkelaars als de product-owner wordt de tester als vanzelf de bruggenbouwer tussen techniek, business en exploitatie.

De tester levert aan alle kanten meerwaarde door te bewaken dat de specificaties de wens van de klant correct en eenduidig weergeven en vervolgens vast te stellen of de kenmerken van het product overeenkomen met de wens van de klant. Ondertussen helpt de tester het proces te versnellen door de juiste testen te automatiseren en kwalitatief goede bevindingen op te leveren. Uiteindelijk vertrouwt het beheer- en exploitatieteam op het advies van de tester als het gaat om het in productie en beheer nemen van het opgeleverde product. Dat vertrouwen moet het team verdienen, maar in het uitdragen daarvan is de grootste rol voor de tester weggelegd.

Is de benodigde skillset dan anders? Er wordt weleens gezegd dat een Agile tester een techneut moet zijn. Dat is in mijns inziens niet noodzakelijk, we hebben immers al ontwikkelaars aan boord voor de technische kennis. Wel is het belangrijk dat de tester affiniteit heeft met dat wat zijn of haar team realiseert. Affiniteit met de techniek, maar net zo belangrijk; affiniteit met de gecreëerde waarde. Idealiter minimaal een beetje van beide. Maar is dat nieuw? Of zijn dat gewoon competenties die elke goede tester bezit?

Vond je dit artikel interessant? Deel het op social media!