Over software testen: bugs

Zoals ik in het vorige deel al heb genoemd, staan er in de ‘issue tracker’ ook ‘bugs’. Over bugs in software kan je boeken vol schrijven, en er kunnen daadwerkelijk mensen aan doodgaan. Een voorbeeld hiervan is de Therac-25 [1]: een bestralingstherapiemachine die teveel straling uitzond doordat mechanische checks uit oudere machines (Therac-6 en Therac-20) vervangen werden door checks in de software in de nieuwste machine (Therac-25), en die bleken niet foutvrij te zijn, waardoor minimaal vier mensen zijn overleden. Uiteraard zijn veruit de meeste bugs niet zo gevaarlijk, want bugs kunnen alleen tot dit soort tragische gevallen leiden in gezondheidskritische software, zoals in de medische wereld, ruimtevaart of auto-industrie. Normaal gesproken kunnen bugs hooguit leiden tot informatie of geld in de verkeerde handen: nog steeds een probleem, maar wel een iets minder groot probleem.

Maar wat is een bug nou eigenlijk? Algemeen gezegd is een bug een fout in de software. Een bug kan je tegengekomen in elke software: ook wat je nu gebruikt om dit te lezen (besturingssysteem, browser, …). Een bug uit zich in de software doordat er iets gebeurd wat niet de bedoeling is, of juist niets gebeurd terwijl er iets zou moeten gebeuren. Lekker vaag allemaal.

Om met een voorbeeld te beginnen: stel je wil twee getallen optellen op een rekenmachine, maar ‘2+3’ wordt ‘6’. Dan heb je een bug gevonden. Die bug kan heel veel verschillende oorzaken hebben: misschien is ‘+’ wel stiekem ‘*’, of misschien telt hij overal wel ‘1’ bij op, of misschien was je vorige antwoord ‘1’ en telt hij dat er bij op, of misschien komt er elke keer een random getal bij. Als tester wil je de oorzaak eigenlijk zo precies mogelijk vaststellen. Je wil weten wat er fout gaat, zodat je beter kan beschrijven wat de bug is en eventueel zelfs hoe een developer hem kan oplossen. En je wil natuurlijk de zekerheid hebben dat het echt een bug is, en niet dat jij per ongeluk iets verkeerd deed. Voor dit geval (‘2+3’ wordt ‘6’) zou je bijvoorbeeld de vier mogelijke oorzaken kunnen testen met ‘3+3’ zoals deze tabel aangeeft:

Tabel met test casesMocht er iets uitkomen wat de tabel zegt, dan heb je (zeer waarschijnlijk) het probleem gevonden! Mocht er iets uitkomen dat je niet had verwacht, dan zal je verder moeten nadenken over wat er mis zou kunnen zijn. Uiteindelijk houdt dat ook wel een keer op: als tester is je verantwoordelijkheid niet om met 100% zekerheid te zeggen waar het probleem zich bevindt, zolang je een goed ‘reproductiepad’ kan geven. Een reproductiepad is namelijk een pad waarmee de bug optreedt: “als je stappen 1, 2, 3 en 4 uitvoert, dan verschijnt ‘6’ in plaats van ‘5’” bijvoorbeeld. Door die stappen te noteren, kan een developer makkelijk de bug reproduceren, waardoor hij zelf (in theorie) heel makkelijk de bug kan oplossen.

Naast het reproductiepad heeft een bug in de issue tracker nog wat meer informatie nodig: een goede titel (wat er mis gaat – en niet de oplossing), een beschrijving (al is vaak een reproductiepad al genoeg), misschien een paar screenshots, een prioriteit (moet de bug vandaag opgelost worden of mag het ook over een jaar?), en allerlei extra bedrijfsspecifieke informatie. Je wil het liefst zoveel mogelijk informatie verschaffen, maar je moet je ook altijd bedenken dat teveel informatie niet nodig is (en dus voor jou tijd kost om de extra informatie te verzorgen, en voor de developer tijd kost om de extra informatie te begrijpen).

Met zo’n bugreport kan vervolgens iets gedaan worden: ofwel kan hij opgelost worden – waarna jij als tester hem weer voor de ogen krijgt en zo kan vaststellen dat de bug inderdaad weg is. Ofwel kan worden besloten om hem niet op te lossen, bijvoorbeeld omdat het gewenst gedrag is (“de rekenmachine onthoudt altijd het vorige antwoord, tenzij op de ‘C’-knop gedrukt wordt”), omdat hij niet te reproduceren is (voornamelijk als er te weinig informatie is aangeleverd) of omdat een ander bugreport precies hetzelfde beschrijft.

Al die bugreports helpen bij het bepalen wat de status is van de software. Mochten er meer bugs worden opgelost dan dat er nieuwe worden gevonden, kan je merken dat de software steeds stabieler wordt. Mocht het andersom zijn, bijvoorbeeld dat er 20 bugs worden opgelost en 30 nieuwe bugs worden gevonden, kan je merken dat er te weinig tijd wordt besteed aan bestaande bugs. En ook dat kan een afweging zijn: als alle nieuwe bugs slechts hele kleine dingen zijn (een spellingfout of iets dat alleen optreedt met Internet Explorer 6 op Windows XP als je linkshandig bent) terwijl de opgeloste bugs de grotere dingen zijn (‘+’ is inderdaad ‘*’), dan kan dat juist een bewuste keuze zijn.

Als tester zou je doel niet moeten zijn om zoveel mogelijk bugs te vinden, want dan ga je juist op zoek naar kleine dingen. Als tester wil je de kwaliteit bewaken en zorgen dat er geen (of zo min mogelijk) bugs in de software zitten die een hoge prioriteit zouden hebben. Dat er een spellingfout instaat is natuurlijk niet heel erg. Dat ‘+’ inderdaad ‘*’ is, is in een rekenmachine juist een heel groot probleem. Je wil als tester aan de andere kant ook juist de kleine dingen vinden, zodat de software uiteindelijk zo perfect mogelijk is. En daarmee zorg je ervoor dat de kwaliteit zo hoog mogelijk wordt. Precies wat de bedoeling is.

Tijdens het testen van een nieuwe feature vind je in eerste instantie nog geen bugs. Een bug is in principe pas een bug als de software opgeleverd is en in gebruik bij eindgebruikers. Daarvoor noem je ze ‘test resultaten’ (of welke andere naam je er ook voor wil gebruiken), omdat ze normaal gesproken nog opgelost worden voordat de software is opgeleverd. Af en toe komt het voor dat er besloten wordt om een test resultaat toch pas later op te lossen, waardoor het dan pas een bug wordt.

[1] Leveson, N. G. & Turner, C. S., “An Investigation of the Therac-25 Accidents”
(1993), IEEE Computer, Volume 26, Number 7, July 1993, pp. 18-41

Dit bericht is geplaatst in de categorie Beta met de tag . Bookmark de permalink.

Geef een reactie

Jouw e-mailadres wordt niet gepubliceerd. Verplichte velden zijn gemarkeerd met *