Testen acht men vooral bestemd voor het vinden van eventuele fouten. Sommige testactiviteiten spelen echter ook een belangrijke rol spelen bij de preventie van fouten en bij de evaluatie van de bereikte kwaliteit. Volgens senior consultant Ed Brandt is het dan ook belangrijk om het testontwerp mede te beschouwen als een preventieve actie tijdens het ontwerptraject.
Bijna een kwart van ons leven investeren we in werk, voor sommigen het alles-omvattende doel. Het is dan ook een geluk dat het meeste werk dat we verzetten ‘goed’ is. Dat wil zeggen dat de meeste resultaten voldoen aan de verwachtingen van degene die ons de opdracht gaf. Op gezette tijden maken we echter – bewust of onbewust – fouten. We nemen verkeerde beslissingen, we doen dingen dubbel, of laten ze ten onrechte achterwege. Daardoor daalt het rendement van de inspanning die we ons getroosten en voldoen de resultaten niet of niet geheel aan de verwachtingen.
Dit gegeven vormt al jaren lang voor talloze specialisten en instellingen een bijna onuitputtelijke bron van inspiratie voor boeken, methoden, visies en protocollen. De overdaad op het gebied van kwaliteitszorg is zo groot, dat het geen kwaad kan om even afstand te nemen en het ‘probleem’ tot ware proporties terug te brengen. Wat we willen is eigenlijk heel simpel:
1) acties om het aantal fouten dat we maken tot een minimum te beperken (preventief);
2) acties om de fouten die we dan toch nog maken zo snel mogelijk te vinden zodat de doorwerking minimaal blijft (correctief);
3) vervolgens aantonen dat daarmee het vereiste kwaliteitsniveau ook daadwerkelijk gehaald is.
Dit alles dient zo efficiënt en effectief mogelijk te gebeuren.
Wanneer we het werk als een black-box beschouwen, dan zijn de preventieve en correctieve acties ook te tekenen als een voorwaartse- en een terugkoppeling op het proces, zie figuur 1.
Door vervolgens twee onderwerpen te onderkennen waarop de acties zich richten – namelijk de produkten die gemaakt worden en de werkwijze waarop dit gebeurt – is een matrix te tekenen zoals weergegeven in figuur 2.
Ter illustratie is daarin een aantal mogelijke acties opgenomen.
Duidelijk is dat ’testen’ in het geheel van de genoemde acties een belangrijke plaats inneemt. In de automatiseringsbranche is dit onderwerp ‘herontdekt’ en heeft het geleid tot een stroom van publikaties en seminars. Testen is weer ‘in’.
Met betrekking tot de bovengenoemde drie punten wordt ’testen’ vooral beschouwd als actie om zoveel mogelijk fouten te vinden. De meeste testmethoden, publikaties, lezingen en dergelijke richten zich op dit aspect en de effectiviteit en efficiëntie daarvan.
Dat sommige testactiviteiten echter ook een belangrijke rol spelen bij preventie van fouten en bij evaluatie van de bereikte kwaliteit, is sterk onderbelicht in de boeken. Concrete handvatten voor toepassing in projecten worden althans niet geboden.
Een volledige visie op ’testen’ zou de gehele regelkring van figuur 1 moeten betreffen. Daarbij spelen de volgende zaken een rol.
– Het ontwikkel- en onderhoudsproces kent invoer in de vorm van functionele- en prestatie-eisen die dusdanig geformuleerd worden dat ze objectief meetbaar zijn.
– Er wordt een meting uitgevoerd op het opgeleverde produkt; deze geeft een waarde in de meeteenheid van de gestelde eisen.
– Er vindt een evaluatie plaats door interpretatie van de gemeten waarden en vergelijking met de normen en eisen.
– Het proces of produkt wordt bijgestuurd op grond van de evaluatie;
– Er worden acties ondernomen om dit gehele traject te beheersen en de resultaten ervan te beheren.
Preventie
De invoer van het testproces bestaat uit kwaliteitseisen ofwel specificaties van de vereiste produktkwaliteit. Deze eisen of specificaties vallen uiteen in functionele- en prestatie-eisen en worden opgesteld aan het begin van het ontwikkel- of onderhoudstraject. Zij vormen als acceptatiecriteria de concrete en meetbare basis voor de acceptatietesten bij oplevering van de produkten.
Hiermee is in vogelvlucht de toepassing van een regelkring op het hoogste niveau van systeemontwikkeling beschreven. De acceptatietest is de meting die waarden oplevert in eenheden waarin de acceptatiecriteria zijn gespecificeerd. De preventieve werking die hiervan uitgaat is evident: ontwikkelaars kennen vanaf het begin van het project de eisen en criteria waarop hun produkt aan het eind van de rit beoordeeld gaat worden. Het blijkt dat alleen daardoor al minder fouten gemaakt worden. Bovendien zal geen enkele projectleider zich permitteren iets op te leveren waarvan hij zelf al heeft geconstateerd dat het niet aan deze eisen en criteria voldoet.
Een volgende preventieve testmaatregel is het opstellen van een testontwerp, simultaan of direct na het opstellen van het ontwerpdocument dat als testbasis dient. Het functioneel ontwerp is zo’n testbasis. Het dient als referentie bij de beoordeling van de functionaliteit van het systeem tijdens de integrale systeemtest. Het ontwerp voor deze test kan echter al opgesteld worden lang voordat de eigenlijke meting wordt uitgevoerd. Sterker nog: aangezien er geen andere informatie nodig is dan het functioneel ontwerp zelf, kan het testontwerp dus gelijktijdig of direct erna worden opgesteld.
Ook hiervan blijkt een sterk preventieve werking uit te gaan. Testontwerpen bevatten kennelijk aanvullende informatie die het voor ontwikkelaars makkelijker maakt het document waarbij deze behoort te interpreteren en te begrijpen. Bovendien heeft het opstellen van het testontwerp ook een controlerende en corrigerende werking op zo’n functioneel ontwerp, zodat hierin minder fouten en onduidelijkheden voorkomen.
Het uitvoeren van statische controles op dergelijke tussenprodukten (dus het functioneel ontwerp inclusief het bijbehorende testontwerp) door middel van reviews of formele inspecties, vormt de laatste stap. Hoewel het eigenlijk een correctieve actie betreft, blijkt het goed in dit rijtje van preventieve acties te passen. Met name het voorkomen van doorwerking van gevonden fouten in volgende trajecten betekent een enorme winst.
De hiervoor beschreven zaken zijn geen nieuwe, laat staan revolutionaire ideeën. De meeste ontwikkelmethodieken schrijven het opstellen van criteria en testontwerpen voor op de momenten zoals hiervoor vermeld, evenals het houden van reviews en inspecties. Omdat de voordelen ervan zo nadrukkelijk te benoemen zijn, zou je verwachten dat elke ontwikkelaar deze principes volgt. Dat blijkt echter niet het geval!
Acceptatiecriteria worden in de praktijk zelden consequent opgesteld en onderhouden, en al helemaal niet vanaf het vooronderzoek. In elk geval zijn ze niet meetbaar. Hetzelfde kan men zeggen van testontwerpen; deze worden niet opgesteld, want testen worden in de praktijk bedacht vlak voor of zelfs tijdens de uitvoering van de daadwerkelijke meting. Ten slotte vinden er zelden reviews en inspecties plaats, ondermeer omdat deze met moderne ontwikkelhulpmiddelen als vierde-generatietalen en i-case-tools overbodig zouden zijn geworden.
Ontbrekende richtlijnen
De hedendaagse benadering van testen lijkt zich bij de hiervoor beschreven fenomenen te hebben neergelegd. Er wordt vooral energie gestoken in de efficiëntie van dynamische testen, door de aandacht te vestigen op testtechnieken, -tools en beheer. Natuurlijk zijn deze aspecten ook van belang. Zij zouden echter vooral moeten worden ingezet om de bereikte kwaliteit aan te tonen en niet zozeer om de vereiste kwaliteit alsnog te bereiken. Die wordt namelijk gemaakt in het ontwerp- en realisatietraject. Derhalve is het veel rendabeler energie te steken in de preventieve testmaatregelen zoals hiervoor beschreven. Dit wordt onomstotelijk aangetoond door ervaringen in de industrie, zie figuur 3.
Bovendien zijn er simulatiemodellen beschikbaar (bijvoorbeeld Checkpoint) waarin op grond van de ervaringen van duizenden projecten voorspellingen gedaan kunnen worden omtrent de effecten van diverse preventieve acties. Zelfs wanneer de voorspellingen als bijzonder rooskleurig worden beschouwd, is het interessant invoering van deze acties te overwegen, zelfs in vierde-generatietaal- en i-case-omgevingen. Waarom gebeurt dit toch niet?
Het antwoord ligt in het feit dat er geen richtlijn is om te komen tot meetbare, specifieke, realistische acceptatiecriteria. Er bestaat geen richtlijn die aangeeft hoe men vanuit een functioneel ontwerp tot een testontwerp komt, gerelateerd aan de gespecificeerde criteria en vereiste dekkingsgraad. Checklists ten behoeve van Fagan-inspecties op criteria en testontwerpen zijn er niet.
Voor een individueel project is de investering in preventieve acties dan ook al gauw een onoverzichtelijke gelegenheid. Het risico dat deze investering zich aan het eind van dat zelfde project niet terug betaalt, wordt als te groot ervaren. En dus gaat men op de oude voet verder.
In dergelijke situaties kan een oplossing alleen worden geboden door een visie of methodiek die een pragmatische invulling geeft aan de specifieke behoefte van een project. Het heeft dan geen zin om een totale testmethodiek te introduceren die van voor tot achter gevolgd moet worden, aanzienlijke papierstromen met zich mee brengt en – als belangrijkste – waarvan het rendement zich slechts na een lange inleerperiode manifesteert. De projectleider of automatiseringsmanager kan beter kiezen voor een verzameling losse bouwstenen, die afhankelijk van de behoefte van de eigen organisatie kan worden ingezet. Een voorbeeld is de richtlijn om te komen tot acceptatiecriteria aan de hand van de kwaliteitseigenschappen zoals die onderkend worden door Serc, inclusief voorbeelden van meeteenheden betreffende beschikbaarheid, betrouwbaarheid en veranderbaarheid. Ook kan men kiezen voor een workshop Fagan-inspecties, inclusief het opstellen van checklists, die ook toepasbaar zijn op moderne ontwikkeltechnieken als jrp en jad.
Evaluatie
Onafhankelijk van het al dan niet toepassen van de hiervoor beschreven preventieve en correctieve acties, zal een opgeleverd systeem niet zonder meer in produktie worden genomen. Men wil eerst beoordelen of het wel ‘goed genoeg’ is. Het eindprodukt wordt daartoe in een afgescheiden omgeving aangeboden aan de acceptanten die dan gaan kijken of het systeem ‘werkt’, hetgeen meestal het begin is van een onbeheersbare lijdensweg voor alle betrokkenen.
De uit te voeren testgevallen worden vaak ter plekke bedacht zonder rekening te houden met dekkingsgraad en testrisico, om maar te zwijgen over herhaalbaarheid en aantoonbaarheid. Men beschouwt het vinden van fouten als doel van de test. Deze worden dan ook direct hersteld waarna de aangepaste programmatuur opnieuw wordt getest. Deze cyclus herhaalt zich tot er geen fouten meer gevonden worden, of – nog erger – tot de tijd om is en het systeem in produktie moet. Mors [1] legt uit dat deze testen om die reden ook de belangrijkste zijn; er worden namelijk de meeste fouten gevonden. Hij beschrijft vervolgens hoe een en ander efficiënt en effectief aangepakt moet worden.
Volgens deze opvatting moet een acceptant zich echter in het beste geval tevreden stellen met de uitspraak: alle testgevallen zijn uitgevoerd en er worden geen fouten meer gevonden. Dat betekent echter niet dat er ook geen fouten meer in het systeem voorkomen. Sterker: het is algemeen aanvaard dat ze nog voorkomen. De organisatie regelt een stand-by en trekt een aanzienlijk budget uit voor correctief onderhoud in de exploitatie-fase. De uitspraak over het niet meer voorkomen van fouten in een testset laat de organisatie echter volkomen in het ongewisse over de te verwachten omvang van het correctieve onderhoud. Wanneer bovendien pas aan het eind van een project de meeste fouten gevonden worden, is er sprake van hoge herstelkosten met een relatief laag rendement. Het project is als een mammoettanker in het zicht van de haven. Je hoeft geen stuurman aan wal te zijn om te onderkennen dat koerswijzigingen dan nog slechts marginaal kunnen zijn.
Bepaling invoeringsrisico
De adequate test-filosofie gaat er daarom vanuit dat een organisatie niet alleen is geïnteresseerd in een foutloze testrun, maar vooral in een betrouwbare voorspelling van het aantal fouten dat zich in de operationele situatie zal voordoen. De evaluatie van testresultaten en met name van het aantal gevonden fouten, de soort en het moment waarop ze optraden, biedt inzicht hierin.
Er staan reeds bruikbare handvatten ter beschikking voor het extrapoleren van aantallen gevonden fouten naar het totaal aantal fouten in het systeem. Deze zijn gebaseerd op modellen zoals die bijvoorbeeld beschreven worden door Neufelder [2], zie figuur 4.
Dit stelt acceptanten in staat een goede afweging te maken ten aanzien van het risico dat de bedrijfsvoering loopt met de implementatie van het nieuwe of gewijzigde systeem. De gegevens die als invoer dienen voor deze modellen worden verzameld tijdens de acceptatietest (of zelfs al tijdens de systeemtest). Nu is het doel van deze test dus niet langer het vinden van fouten, maar het vastleggen van testresultaten ten behoeve van een betrouwbare bepaling van het invoeringsrisico. Dat stelt wel enige eisen aan het testontwerp, zie figuur 5.
Deze eisen gaan ondermeer in op het fenomeen ‘dekkingsgraad’ van een testset. Om een betrouwbare uitspraak te doen over het invoeringsrisico is het van belang een goed inzicht te hebben in dat deel van het systeem dat door de testgevallen is gedekt. Bovendien wordt niet elk deel van het systeem in produktie even vaak gebruikt; ook deze frequentie is dus van belang. Ten slotte wordt het invoeringsrisico bepaald door de schade die een organisatie kan oplopen. Daarbij dient men onderscheid te maken tussen interne en externe schade en schade als gevolg van doorwerking van een opgetreden fout.
Al met al een complex van factoren die onmogelijk zijn te overzien door individuele testers tijdens het uitvoeren van de testgevallen. Daarom moet het ontwerp voor de (acceptatie)test al liefst ver voor de eigenlijke uitvoering gemaakt worden. Wanneer men het testontwerp ook beschouwt als preventieve actie tijdens het ontwerptraject is dat exact het geval.
Kwaliteitszorg
Het beschouwen van de preventieve, correctieve en evaluatie-acties als afzonderlijke bouwstenen is natuurlijk één manier van afstand nemen. Kwaliteitszorg op zich wordt hiermee niet minder belangrijk, maar wel overzichtelijker. Bij het groeien naar nieuwe stadia van volwassenheid zal elke organisatie afzonderlijk zich moeten afvragen welke bouwstenen van toepassing kunnen zijn. De daarvoor benodigde helikopter-view is een andere manier van afstand nemen, die wellicht hetzelfde resultaat oplevert. Stel bijvoorbeeld aan de hand van het capability maturity model [3] de lange termijn visie vast, en bepaal vervolgens welke kwaliteitsacties in welke volgorde opgepakt moeten worden, zie figuur 6.
Beide benaderingen stellen echter dezelfde eis aan de ondersteunende visie en methodiek: biedt praktische handvatten voor het stapsgewijs invoeren van kwaliteitsacties, die elk op zich aantoonbaar rendement opleveren.
Alleen dan hoeven afzonderlijke projecten niet steeds zelf opnieuw het wiel uit te vinden en blijkt het begrip ’testen’ tijdloos.
Ed Brandt is produktmanager en senior consultant Testen bij Maintain Software Management bv.