Testen kost tijd

Bij testen zie ik nogal eens onbegrip als het
gaat om de testduur.  Simpel gezegd, je kijkt
of iets het doet, en zo ja, dan doetie het de
volgende keer toch ook?  Dus hoe kan testen nu
tijd kosten?  Een begrijpelijk punt bezien vanuit
de leek, en het valt niet mee om dat in simpele
taal uitgelegd te krijgen.  Dat komt omdat de
mens doorgaans lineair denkt.  Het antwoord op
de vraag:  "Hoe dik wordt een A4tje als je het
vijftig keer opvouwt?" is dan ook niet standaard:
"Van hier tot de zon".

Software is vaak veel complexer dan een
lichtknopje aan of uit doen, en dat wordt
uitgedrukt in de broncode.  Je kunt vele
gevalsonderscheidingen verwerken in broncode.
Dat doe je bijvoorbeeld door case statements,
via conditionele constructies (IF-THEN-ELSE),
of loop constructies.

Je kunt het aantal verschillende paden dat een
programma kan doorlopen meten door in de broncode
het aantal mogelijke besluiten te tellen.  Kort
gezegd, als er een IF-THEN-ELSE constructie in
broncode zit, heb je twee paden.  Of de IF-tak
wordt uitgevoerd, of de ELSE-tak.  Als je dus
beide takken wilt testen moet je in ieder geval
twee tests uitvoeren.

Stel nu eens dat er binnen die IF-THEN-ELSE
constructie nog een stukje broncode staat waarin
een besluit kan vallen.  Dan hebben we vier
gevallen om alle takken te testen.  Als nu
binnen dit construct weer een conditioneel
statement zit, loopt het aantal paden wat een
programma kan aflopen exponentieel op.  Als nu
ook de condities zelve complex zijn voegt dat
nog meer mogelijkheden toe omdat er dan sprake
is van samengestelde besluitmomenten.

Als broncode complexe gevalsonderscheidingen
bevat, wordt het aantal paden dat een programma
kan doorlopen groter en groter.  Het grote
nadeel van een hoog aantal geneste beslismomenten
is dat het aantal te testen  paden enorm
toeneemt.  De tijd die daarmee dus gemoeid is,
en de hoeveelheid werk om al die testgevallen
te construeren, neemt daarmee ook enorm toe.

Een belangrijke reden dat testen dus veel tijd
kan kosten is de complexiteit van het te testen
object.  Naarmate de broncode complexer is, is
de testtijd langer.  Naarmate het aantal paden
toeneemt, neemt de begrijpelijkheid van de
broncode af.  En als het aantal beslispaden
groot genoeg is, dan zul je ondanks langere
testtijden toch hele gedeeltes van de broncode
nooit doorlopen.  Dus te complexe software
heeft een groot risico dat significante gedeeltes
ongetest in productie gaan.

Daarmee is ook de kiem gelegd voor onderhoudsproblemen.
Stel namelijk dat er in toch al complexe broncode
een nieuwe gevalonderscheiding nodig is.  Hoe
ga je dat aanpakken?  Er is de structurele
oplossing, die varieert van een volledige
analyse van alle beslispaden tot een rigoreus
herontwerp van de bestaande broncode.  Dat kost
tijd, en dat is programmeurs meestal niet
gegeven door bestuurders.  Dat heeft tot gevolg
dat bij aanpassingen van de software code-stapeling
zal plaatsvinden.  De programmeur copieert de
toch al warrige code en voegt het geheel toe
aan de gevalsonderscheidingen die er al waren,
plus een kleine variatie voor de uitbreiding
die gewenst was.

Dat betekent dat als de tijd verstrijkt, de
broncode almaar complexer wordt, en dat die
complexiteit sneller toeneemt naarmate er meer
code-stapeling optreedt.  Op een gegeven moment
neemt het aantal onafhankelijke paden dat de
software kan doorlopen dusdanig toe dat de
software ontestbaar geworden is.  Het aantal
nodige testgevallen is dusdanig hoog geworden
dat ook als je veel testtijd beschikbaar stelt,
je er toch niet doorheen komt.

Als je dit nu in het groot doet, dan zijn de
rapen helemaal gaar.  Stel je hebt een aantal
van dit soort systemen die gekoppeld zijn om
tot een integrale systeemprestatie te komen.
Denk hierbij aan systeemcomplexen bij banken,
overheid, of in de procesindustrie.  Vele van
die systemen samen zorgen voor uiterst uitdagende
condities om te testen.   Niet alleen hun
intrinsieke soms al veel te hoge complexiteit,
maar ook nog eens door de ingewikkelde correlaties
tussen de systemen onderling om tot gewenst
systeemgedrag te komen, leveren zeer diepe
nesting op van beslismomenten.

De ordegroote van het aantal tests wat nodig
is voor volledige coverage van alle paden in
een systeemcompleex wordt bepaald door de diepst
aangetroffen nesting.  Bij 1 beslispunt is dat
twee tests.  Bij een nesting van twee, is dat
vier tests.  Bij drie is het acht, en bij vier
is het zestien.  Bij vijftig is het dus twee
tot de macht vijftig.  Een 1 met vijftien
nullen.  Met andere woorden als er op ook maar
1 plek in je systeem(complex) een dergelijke
nesting zit, is het geheel effecief ontestbaar.
Dat nu verklaart waarom testen in vele gevallen
langer zal duren dan bestuurders denken.  En
het verklaart ook waarom mensen niet meteen
doorzien dat een A4tje 51 keer dubbelvouwen
een dikte oplevert van hier tot de zon.  En
terug.

X

Meer weten over de wondere wereld van ICT
in Jip en Janneke taal? Ga dan naar de
knipselkrant van Chris Verhoef

Prof. dr Chris Verhoef is hoogleraar informatica
aan de Vrije Universiteit in Amsterdam en
wetenschappelijk adviseur voor overheid en
bedrijfsleven.  Hij schrijft regelmatig een
column in AG II.  Hij is te bereiken via email:
x@cs.vu.nl.  Deze tekst is copyright SDU.  Niets
van deze uitgave mag zonder schriftelijke
toestemming van de uitgever worden overgenomen of
worden gepubliceerd.