Onderhoudbaarheid tip 4: automatiseer testen

Door Victor van der Hulst In Smart@Vantage

De afgelopen weken heb ik stilgestaan bij het belang van onderhoudbaarheid van maatwerk applicaties, hoe een Agile ontwikkelaanpak hieraan bijdraagt, hoe de mate van onderhoudbaarheid kan worden gemeten en hoe deze opgebouwde technical debt met refactoring kan worden aangepakt. Deze week sta ik stil bij de rol van testen en geautomatiseerd testen in het bijzonder.

Testbaarheid zorgt voor onderhoudbaarheid

Zoals in het eerste deel besproken, betekent onderhoudbaarheid onder andere testbaarheid en wijzigbaarheid. Vaak zien we dat in de onderhoudsfase van een applicatie de complexe onderdelen niet door iedereen gewijzigd kunnen worden. Bijvoorbeeld dat ontwikkelaars een wijziging niet durven door te voeren, vanwege onvoorziene effecten op de applicatie. Wijzigingen moeten dan vaak door dezelfde personen uitgevoerd worden, waardoor een applicatie aan mensen ‘blijft plakken’. Een onwenselijke situatie. Blijkbaar is de testbaarheid dermate laag, waardoor de wijzigbaarheid in het geding is. Wie brandt z’n handen aan een wijziging die onvoorziene(!) effecten heeft op de werking van een applicatie?

onderhoudbaarheid-tip-4-automatiseer-testen-blog-victor

Automatiseer testen

Door vanaf het begin te zorgen voor testbaarheid, wordt de wijzigbaarheid groter. Wanneer je door middel van een test zeker kunt zijn of de gewijzigde functionaliteit blijft werken volgens de specificatie, is de drempel lager voor het maken van de wijziging. Als ontwikkelaar kun je namelijk vertrouwen op de aanwezige testen (let op: niet teste

r). Echter, elke regel code testen is simpelweg te duur en onnodig. Maak een risicoanalyse en focus op de onderdelen die niet triviale business logica bevatten en waar veel schade mee veroorzaakt wordt bij disfunctioneren. Deze analyse voer je uit samen met de business verantwoordelijke(n), door te kijken naar kans en impact. Kennis van teststrategieën helpt tijdens deze exercitie. Voor de hoog-risico-onderdelen moet gelden dat er geen fouten worden aangetroffen in de opgeleverde applicatie. Het ontwikkelteam dient dit als doel te hebben. En door het ontwikkelteam verantwoordelijk te maken voor de kwaliteit en daarmee de testen, worden testen sneller geautomatiseerd. Ontwikkelaars hebben namelijk de neiging repeterend werk te automatiseren, wat leidt tot testscripts. Dit geldt voor alle niveaus: unittesten, integratietesten, ketentesten, performancetesten, penetratietesten, etc. Wanneer je als ontwikkelaar vervolgens kunt vertrouwen op de aanwezige testen, is het doorvoeren van wijzigingen minder risicovol. Onvoorziene *side effects** *worden namelijk direct zichtbaar in de testresultaten.

Mutation testing

Toch worden onvoorziene 

side effects soms helemaal niet opgemerkt door falende testen. De testen gaan goed en toch is de werking incorrect. Hoe zit dat? Er moet niet alleen aandacht zijn of alle (te testen) code wordt afgevangen door testen (code coverage), maar ook of de testen daadwerkelijk juist zijn. Oftewel: quis custodiet ipsos custodes (wie zal de bewakers zelf bewaken)? * Met mutation testing worden ‘mutanten’ gegenereerd van de code, die ervoor moeten zorgen dat de testen falen. Wanneer de testen niet falen, is een mutant ontdekt die zorgt voor een foutieve werking, zonder de testen te laten falen. Voorbeelden van mutanten zijn het omdraaien van *booleans (true en false), wijzigen van operators (+, -, …) en verwijderen van statements.

onderhoudbaarheid-tip-4-automatiseer-testen-blog-victor-02

Up-to-date specificaties en ATDD

Uitdaging bij het opzetten van testen zijn de specificaties. Testen worden vaak opgezet op basis van de specificaties, waarbij het uitgangspunt is dat deze kloppend zijn met de daadwerkelijk gebouwde functionaliteit. Naar mate een applicatie verder in de levensfase zit, zien we dat het lastig is dit vol te houden. Specificaties gaan afwijken (doordat deze bijvoorbeeld niet consequent zijn bijgewerkt), waardoor discussie ontstaat over de juiste werking. De laatste jaren zien we steeds vaker dat specificaties in de vorm van een testscenario worden opgesteld. We noemen dit 

Acceptance Test Driven Development (ATDD). Door specificaties op deze manier op te stellen, kan geen verschil ontstaan tussen de specificaties, de testscripts en daarmee de functionele werking van de applicatie. Over het algemeen wordt dit formaat gebruikt:

Given (setup)      A specified state of a system When (trigger)      An action or event occurs Then (verification)      The state of the system has changed or an output has been produced

Dit formaat zorgt ervoor dat ook business verantwoordelijken in staat zijn de scenario’s te lezen, te begrijpen en na wat oefening op te stellen. Dit beperkt het risico op misinterpretatie, een ander bekend fenomeen binnen software development.

Cucumber

Tools als 

Cucumber en SpecFlow maken het mogelijk dit soort scripts te automatiseren waardoor ze uitvoerbaar worden. Hiermee is het gat tussen specificaties, testen en daadwerkelijke code gedicht. En testbare code is onderhoudbare code! Naast geautomatiseerd testen is exploratory testen een manier om vast te stellen of de applicatie correct functioneert onder menselijk gebruik. Mensen zijn creatief in het gebruik van software. Creatiever dan testscripts kunnen afdekken. Het gaat hier dan ook niet om code coverage, maar logisch (menselijk) gedrag. Crowd testen is hier een goed voorbeeld van. Stel de applicatie beschikbaar aan een grote groep testers en betaal ze voor bevindingen in plaats van de geleverde inspanning. Kijk bijvoorbeeld eens naar platformen als Testbats. Volgende week aandacht voor de infrastructuur. Tot op heden focussen we ons op het maken van code. Onderhoudbaarheid beperkt zich niet tot de code en wordt ook bepaald door de infrastructuur waar de applicatie op draait.

Meer informatie

victor-van-der-hulst

Victor van der Hulst

Managing Consultant

+31 6 22 98 68 76 Stuur Victor een e-mail

Reacties

Er zijn nog geen reacties op dit bericht.

Plaats een reactie

Dit veld is verplicht.

Vul een geldig e-mailadres in.

Dit veld is verplicht.