Voor een optimaal resultaat dient men bij het testen van software rekening te houden met factoren die te maken hebben met de menselijke aard. Jan Erik van der Laan schetst daarom in zijn derde en laatste artikel van deze serie de psychologische kant van het testen.
Volgens Glenford Meyers [1] zijn de belangrijkste randvoorwaarden bij het testen van software te vinden in de psychologie. Hiervan uitgaande kan een set van vitale testprincipes worden geïdentificeerd. De meeste liggen schijnbaar voor de hand. Ze worden echter maar al te vaak vergeten.
Het is duidelijk dat deze psychologische aspecten geen rol spelen wanneer men test met behulp van de computer. Ze spelen echter weer wel mee bij het opzetten van de cast-omgeving, het definiëren van de testspecificaties, het invoeren van de testgevallen, enzovoort.
Ter illustratie van het belang van de psychologische kant van het testen wordt hieronder een aantal stellingen geponeerd.
Een onontbeerlijk onderdeel van een testgeval is een definitie van de verwachte uitvoer of het resultaat.
Zondigen tegen dit voor de hand liggende principe is één van de meest gemaakte fouten bij het testen van programma’s. De verklaring is te vinden in de psychologie. Wanneer het verwachte resultaat van een testgeval niet is gedefinieerd, bestaat er een goede kans dat een plausibel maar fout resultaat wordt geïnterpreteerd als een correct resultaat. ‘Het oog ziet wat het wil zien’. Ondanks het juiste, ‘destructieve’ karakter van testen is er nog steeds een onbewust verlangen om het correcte resultaat te zien. Een manier om dit te voorkomen is het aanmoedigen van een gedetailleerd onderzoek van alle uitvoer, door deze vooraf uiterst gedetailleerd te beschrijven. Om deze reden dient een testgeval uit twee delen te bestaan: een beschrijving van de invoerdata voor het programma en een gedetailleerde beschrijving van de correcte uitvoer van dat programma bij die specifieke invoer.
De noodzaak hiervan wordt benadrukt door de logicus Copi [2] die stelt dat een probleem verwachtingen vooronderstelt. Indien deze ontbreken, doen zich ook geen verrassingen voor.
Een programmeur dient het testen van eigen programma’s te
vermijden.
Dit principe vloeit voort uit de hierboven gestelde opmerking dat testen een destructief proces is.
Psychisch is het zeer moeilijk voor een programmeur om het eigen programma met een volledig destructieve blik te bekijken. Hij of zij is immers lange tijd constructief bezig geweest met het ontwerpen en bouwen van dit programma. Zoals veel huiseigenaren weten is het verwijderen van behang (een destructief proces) niet leuk. Het is echter ongelofelijk deprimerend wanneer je zelf de behanger bent geweest. Hieruit volgt dat de meeste programmeurs hun eigen programma’s niet effectief kunnen testen omdat ze niet tot de juiste mentale instelling kunnen komen: de instelling om fouten te willen vinden.
Daarnaast is er een tweede belangrijk probleem: het programma kan fouten bevatten die voortvloeien uit een verkeerd begrip dat de programmeur heeft van het gestelde probleem of de specificatie. Wanneer dit het geval is, is het aannemelijk dat die programmeur dezelfde fout zal maken wanneer hij of zij het programma probeert te testen.
Testen lijkt op het redigeren of beoordelen van een boek of essay. Veel schrijvers vinden het moeilijk om het eigen werk te redigeren of te beoordelen. Het vinden van fouten in eigen werk schijnt in te druisen tegen de menselijke psyche.
Dat wil niet zeggen dat het onmogelijk is om eigen programma’s te testen. In het verleden zijn enige successen geboekt bij het testen van hun programma’s. Maar het is wel zo dat tests effectiever en succesvoller zullen zijn wanneer ze door een ander worden uitgevoerd.
Het bovenstaande heeft geen betrekking op het debuggen (corrigeren van bekende fouten) van programma’s; dit gebeurt zelfs het meest effectief door de oorspronkelijke programmeur.
Een programmeer-afdeling zou de eigen programmatuur niet moeten testen.
Het argument voor deze stelling is vergelijkbaar met het voorgaande. Een (programmeer-)afdeling is in veel opzichten een levend organisme met vergelijkbare psychologische problemen. Daarnaast wordt een project-manager in veel omgevingen grotendeels beoordeeld op zijn (on)vermogen om een programma met het beschikbare budget op de gestelde datum op te leveren. Het meten van tijd en kosten is namelijk eenvoudig; het kwantificeren van de betrouwbaarheid van een programma daarentegen niet. Het is moeilijk voor een programmeer-afdeling om volledig objectief te zijn bij het testen van de eigen programmatuur. Dit komt voort uit de gedachte dat het testproces – benaderd vanuit het juiste standpunt – de kans vermindert om het project binnen de gestelde tijd en kosten op te leveren.
Ook hier geldt dat een programmeer-afdeling een aantal eigen fouten kan vinden. Maar het is economischer om het testen te laten uitvoeren door een objectieve, onafhankelijke partij.
Inspecteer de resultaten van iedere test grondig.
Dit is waarschijnlijk de meest voor de hand liggende stelling, die echter regelmatig wordt vergeten. De ervaring leert dat zelfs fouten die duidelijk op uitvoerlijsten zijn te onderscheiden, veelal over het hoofd worden gezien. In de praktijk blijkt dat een belangrijk percentage van de fouten die uiteindelijk worden gevonden, reeds eerder door andere tests zichtbaar was gemaakt. Deze fouten worden te laat ontdekt wegens het ontbreken van een grondige inspectie van de resultaten van eerdere tests.
Testgevallen moeten worden ontworpen voor zowel foute en
onverwachte als voor correcte en verwachte invoer.
Er bestaat een natuurlijke neiging om bij het testen van programma’s de nadruk te leggen op correcte en verwachte invoer, terwijl de foute en onverwachte invoer wordt verwaarloosd. Veel fouten komen aan het licht wanneer het programma op nieuwe of onverwachte wijze wordt gebruikt. Testgevallen voor onverwachte en foute invoer blijken dan ook meer fouten te ontdekken dan testgevallen die zich op de juiste en verwachte invoer concentreren.
Onderzoeken of een programma niet doet wat het zou moeten doen is slechts het halve werk. Daarnaast dient men te onderzoeken of het programma doet wat het niet zou moeten doen.
Dit is simpelweg een bevestiging van het voorgaande principe. Het impliceert tevens dat programma’s moeten worden onderzocht op ongewenste neven-effecten. Een salarisprogramma dat bijvoorbeeld naast de correcte salarissen tevens salarissen genereert voor niet-bestaande werknemers, is een fout en dus onbetrouwbaar programma.
Vermijd ‘weggooi’-testgevallen tenzij het werkelijk ‘weggooi’-programma’s betreft.
Dit probleem komt het meest voor bij het gebruik van interactieve systemen voor het testen van programma’s. Zo komt het in de praktijk vaak voor dat men achter een terminal plaatsneemt, ad-hoc testgevallen bedenkt en deze in het programma invoert.
Het grootste probleem hierbij is dat testgevallen kostbare investeringen vertegenwoordigen die in dit geval verdwijnen na het uitvoeren van de test. Wanneer het programma aan een nieuwe test toe is (bijvoorbeeld na het corrigeren van een fout of het aanbrengen van een verbetering) moeten de testgevallen opnieuw worden bedacht. Omdat het opnieuw bedenken en invoeren van testgevallen een aanzienlijke hoeveelheid werk betekent, heeft men vaak de neiging om dit achterwege te laten. Hierdoor blijkt het hertesten van een programma vaak niet zo grondig te worden uitgevoerd als de originele test. Dit betekent dat wanneer de aanpassing een voorheen functionerend deel van het programma beschadigt, deze fout veelal niet of te laat wordt ontdekt.
Het is dus van belang om testgevallen vast te leggen en te documenteren, zowel uit economisch als uit quality assurance-perspectief.
Plan uw test(inspanning) in de veronderstelling dat er (wel) fouten worden gevonden.
Projectmanagers gaan op dit punt vaak in de fout. Het is onjuist te veronderstellen dat testen een proces is dat aantoont dat een programma correct functioneert.
De waarschijnlijkheid dat er meer fouten in een deel van een programma bestaan is proportioneel aan het aantal fouten dat reeds gevonden is in dat deel van het programma.
Op het eerste gezicht lijkt deze stelling van weinig betekenis, maar dit fenomeen is waargenomen in veel programma’s. Stel een programma bestaat uit twee modules of subroutines A en B, en er zijn bij gelijkwaardige tests tot nu toe vijf fouten gevonden in module A en slechts één in module B. Dan vertelt deze stelling ons dat de waarschijnlijkheid dat er meer fouten in module A bestaan groter is dan de waarschijnlijkheid van meer fouten in module B. Met andere woorden: fouten lijken te bestaan in clusters. In de meeste programma’s zijn bepaalde secties meer fout-gevoelig dan andere; tot nu toe heeft niemand hiervoor een goede verklaring voor kunnen vinden. Dit fenomeen is bijvoorbeeld ook waargenomen in IBM’s S/370 operating systems. In één van deze operating systems bleek dat 47 procent van de (door gebruikers ontdekte) fouten werd ontdekt in slechts 4 procent van de modules in het systeem.
Dit fenomeen is bruikbaar omdat het ons inzicht geeft in de feedback van het testproces. Wanneer een bepaalde sectie van een programma meer fout-gevoelig blijkt dan andere secties, vertelt dit fenomeen ons dat – in termen van opbrengst van de testinspanning- aanvullende tests het beste kunnen worden geconcentreerd op deze fout-gevoelige secties.
Testen is een uiterst creatieve en intellectueel uitdagende opgave.
Het is waarschijnlijk waar dat de vereiste creativiteit voor het testen van een groot programma groter is dan die welke nodig is voor het ontwikkelen van dat programma. We hebben reeds gezien dat het onmogelijk is om een programma zodanig te testen dat er een garantie op de afwezigheid van fouten te geven is. Er zijn methoden die het mogelijk maken om een redelijke set van testgevallen voor een programma te ontwikkelen, maar ook bij deze methoden is een belangrijke dosis creativiteit onontbeerlijk.
Vier basisprincipes
De hiervoor genoemde stellingen en gedachten kunnen worden samengevat in de volgende vier belangrijke basisprincipes:
Testen is het proces van het uitvoeren van een programma met als doel het vinden van fouten.
Een goed testgeval biedt een grote kans om nog niet ontdekte fouten zichtbaar te maken.
Een succesvol testgeval maakt een tot nu toe niet ontdekte fout zichtbaar.
Een goede tester beschouwt het vinden van fouten als belangrijkste doel.
Jan Erik van der Laan is werkzaam als general manager/qa-consultant bij QES/Europe te Joure.
Literatuur
1. Glenford Meyers, The art of software testing.
2. I.M. Copi, Introduction to logic. New York: Macmillan,1968.