Syftet med testningen – är vi säkra på att vi förstår?

Varför denna artikel?

I mitt dagliga värv som konsult och lärare inom testning av mjukvara stöter jag ofta på situationer där man inte till fullo drar nytta av kopplingen mellan syftet med testningen och det manöverutrymme som testare och testledare har i en specifik situation. Detta kan ta sig uttryck i att man använder mindre effektiva testmetoder, att man formulerar tandlösa startkriterier eller att man helt enkelt använder resurser på fel saker.  Därför vill jag med denna artikel reda ut en del begrepp kring syften med testning samt hur detta påverkar våra möjligheter att agera under testningens genomförande med förhoppning om att testning i allmänhet ska kunna bedrivas mer effektivt.

Olika möjliga syften med testning

I standardlitteratur, t.ex. ISTQB syllabi, brukar man ofta beskriva två delvis komplementära huvudsyften med testning. Antingen kan testverksamhet användas för att (1) stödja produktkvaliteten eller så kan testverksamheten användas för att (2) mäta kvalitet. Till dessa huvudsyften tillkommer ibland syftena med testning att dels (3) göra det troligt att man uppfyller krav ställda i ett kontrakt eller i en standard och dels att (4) göra det troligt att systemet är redo för driftsättning.

1) Testning som kvalitetsstödjande aktivitet

Att testning kan användas för att stödja produktkvaliteten är enkelt att inse. Varje gång en avvikelse identifierats och rapporterats kan man välja att a) åtgärda den defekt som orsakar avvikelsen, b) att identifiera en s.k.  ”work-around” som begränsar eller helt tar bort konsekvenserna av avvikelsen eller c) att leva med den identifierade avvikelsen. I synnerhet i det första fallet, men även i det andra fallet, ökar den upplevda produktkvaliteten. Testningen triggar alltså i dessa fall kvalitetsförbättringar av produkten. Notera dock att det inte är testningen i sig som ökar produktkvaliteten – det är samma produkt både före och efter själva testningen.

När testning används som kvalitetsstödjande aktivitet bör inriktningen alltså vara mot att identifiera och dokumentera så många avvikelser som möjligt. Om man dessutom kan rikta testningen mot problem som är särskilt viktiga för en slutanvändare eller kund så är detta ett plus.

2) Testning som kvalitetsmätande aktivitet

Testning kan även användas för att mäta kvalitet. Här är det inte riktigt lika enkelt att se hur testningen kan bidra. I den bästa av världar skulle vi ha ett väldefinierat mått på produktkvalitet som skulle vara enkelt att använda och förstå. Man skulle då kunna formulera ett kvalitetsmål för sitt testobjekt och därefter arbeta omväxlande med implementering och testning tills denna kvalitet är uppnådd. Tyvärr är detta ganska svårt i praktiken, främst därför att begreppet produktkvalitet inte enkelt låter sig beskrivas och för att detta begrepp sannolikt innehåller ett visst mått av subjektivitet. Ofta väljer man därför att approximera produktkvalitet med det trubbiga måttet ”antal just nu kända fel”. Om vi har många kända fel är det enkelt att dra slutsatsen att produktkvaliteten är låg. Däremot innebär inte ett litet antal kända fel automatiskt att produktkvaliteten är hög eftersom få kända fel kan bero antingen på bra kvalitet eller på dålig (eller obefintlig) testning eller båda i samverkan. Alltså behöver vi komplettera denna trubbiga produktkvalitetsmätning, i form av antal kända fel, med mätningar av testkvaliteten. Turligt nog är begreppet testkvalitet enklare att undersöka, via olika former av täckningsmått. Om vi med exekverade testfall har täckt kraven, själva mjukvaran och eventuella produktrisker och vi fortfarande har ett lågt antal kända fel, då ligger slutsatsen nära till hands att produktkvaliteten faktiskt motsvarar förväntningarna.

Alltså kan man se att när testning ska användas för att mäta produktkvaliteten så behöver man inrikta testningen mot de i förväg överenskomna täckningsmålen, d.v.s. välja testmetoder som stödjer de täckningsmått som målen är formulerade i.

3) Testning för att verifiera kravuppfyllning

De flesta system och produkter utvecklas med någon form av kravspecifikation som bas. I synnerhet när beställaren av systemet är extern, men även vid intern utveckling brukar det finnas någon form av kontrakt som via referenser till dessa kravspecifikationer pekar ut vad det beställda systemet ska innehålla. I vissa fall kan det även finnas olika typer av standarder, t.ex. kommunikationsprotokoll som måste uppfyllas.

Här vore det naturligtvis perfekt om testningen skulle kunna bevisa att systemet uppfyller kraven. Tyvärr är detta en utopi eftersom ett bevis skulle kräva att varje möjligt testfall skulle exekveras, vilket i praktiken är omöjligt då antalet möjliga testfall är enormt, många gånger oändligt. Testning blir därför en form av stickprovstagning där testaren identifierar en delmängd testfall som exekveras och på basis av deras resultat görs antaganden om hur systemet beter sig i det allmänna fallet. I och med stickprovstagningen uppkommer ett representativitetsproblem. Hur säkra kan vi vara på att resultaten hos den mängd testfall vi valt ut även representerar resultaten hos de testfall vi inte exekverat? Detta innebär att testaren hänvisas till att bygga förtroende för den testade produkten via testfall som exekveras.

Ett godkänt testfall ökar alltid tron på att systemet fungerar som avsett, men olika testfall kan bidra olika mycket till den ökade trovärdigheten Till exempel kommer testfall kopplade till viktiga krav att ge större ökning av trovärdigheten hos systemet än testfall kopplade till mindre viktiga krav. Vidare kommer även ordningen mellan testfallen att kunna spela roll. Det första av två snarlika testfall kommer att öka trovärdigheten mer än det andra testfallet, oavsett ordning.

Testning för att verifiera kravuppfyllning innebär alltså att testningen bör göras utifrån de ställda kraven samtidigt som man väger in användarens behov och allvarligheten hos konsekvenser av eventuella avvikelser, d.v.s. risk. Krav- och risk-täckning spelar roll i dessa sammanhang. Även exekveringsordning kommer att påverkas, men oavsett så kommer man alltid här att behöva brottas med representativitetsproblemet.

4) Testning som bas för driftsättning

Innan man tar en ny version av ett befintligt system (eller ett helt nytt system) i skarp drift behöver man förvissa sig om att systemet kommer att klara själva driftsituationen. Även om tidigare genomförd testning indikerar att systemet uppfyller de ställda kraven är det troligt att dessa tester genomförts i en miljö som inte är identisk med själva driftsmiljön, både med avseende på fysisk konfigurering och på volym samt sammansättning av lasten. På grund av detta väljer man ibland att genomföra dedicerade tester av systemet inför den skarpa driftsättningen, i synnerhet i de fall då ett driftsavbrott skulle vara kostsamt eller besvärligt att hantera.

Ett vanligt sätt att agera är att under en inkörningsperiod köra det nya systemet parallellt med det befintliga för att kontrollera att det nya systemet är tillräckligt stabilt för att ensamt ta över driften. Eftersom man kör det nya systemet med riktig trafik har man här inget representativitetsproblem. Däremot kan man ibland ha svårt att avgöra hur länge man ska köra de båda systemen parallellt och det kan dessutom kosta både tid och pengar att ha båda systemen igång samtidigt.

Konsekvenser av olika syften med testning

Ovan illustrerades olika tänkbara syften med testning. Det är lätt att inse att det valda syftet kommer att ha stark påverkan på både hur testningen ska genomföras och det manöverutrymme testare och testledare har vid oförutsedda situationer. Följande tre exempel illustrerar denna påverkan ytterligare.

Exempel 1: Val av testtekniker

Tekniker för att skapa testfall brukar i en del litteratur delas in i tre grupper 1) Specifikationsbaserade (black-box), 2) Strukturbaserade (white-box) samt 3) Erfarenhetsbaserade. Teknikerna inom var och en av grupperna har vissa gemensamma nämnare som kan knytas till olika syften med testverksamheten.

Specifikationsbaserade testtekniker har vanligtvis någon form av associerade täckningsmått som direkt eller indirekt kan relateras till kravtäckning. Kravtäckning är en viktig aspekt av testkvaliteten i och med att alla otestade krav medför en risk att produkten inte uppfyller dessa krav. Därmed kan man argumentera för att när syftet med testningen är att mäta kvaliteten eller verifiera kravuppfyllning så är specifikationsbaserade tekniker centrala.

Även strukturbaserade testtekniker har associerade täckningsmått, men inte mot kraven utan mot själva strukturen i implementeringen. Strukturbaserade testtekniker erbjuder alltså en möjlighet att utvärdera testkvaliteten med avseende på vilka delar av koden som testats. Av samma skäl som ovan kan kommer även strukturbaserade testtekniker att vara viktiga då syftet med testningen är att mäta kvaliteten.

Erfarenhetsbaserade testtekniker har ofta fokus på problemområden och defekter. Därför utgör dessa tekniker naturliga val när testningens syfte är att stödja kvaliteten, d.v.s. då fokus ligger på att hitta och rapportera fel i systemet. Vissa erfarenhetsbaserade testtekniker har även fokus på hur användaren jobbar med systemet. Därför kan dessa metoder även vara intressanta då syftet med testningen är att undersöka om systemet är redo för driftsättning – även om denna typ av testning inte i normalfallet bygger på att testaren konstruerar egna testfall.

Utöver detta kan man för vissa testtekniker se egenskaper som gör dessa lämpliga i specifika situationer. Till exempel kan användningsfallsbaserad testning, vilken är en specifikationsbaserad teknik, med fördel användas vid testning för att öka trovärdigheten hos systemet.

Exempel 2: Rapportering

Centralt i all rapportering är att anpassa formen på budskapet efter mottagaren och att tillhandahålla lagom mycket information. Utöver detta kommer syftet med verksamheten att ha en påverkan på hur man rapporterar. Syftet med en verksamhet bör ju avspegla sig i de mål man formulerat och därmed de mätetal man väljer att använda för att övervaka verksamheten.

För alla verksamheter finns ett måldatum som man styr mot, vilket innebär att kalendertid, t.ex. dagar eller timmar kommer att vara ett viktigt mätetal. I många fall finns även en kostnadsaspekt med i bilden, antingen i form av direkta pengar eller i form av ”mantid”. Dessa båda storheter (tid och pengar) är alltså gemensamma oavsett syfte.

Om syftet är att stödja kvaliteten (hitta fel) är det lämpligt att fokusera mätning och rapportering på olika aspekter av fel. Dels kan man jobba med ”antal just nu kända fel”, eventuellt med kosmetiska fel borträknande, och dels kan man jobba med ”felupptäckarintensitet”. Det senare är centralt i sammanhang då fokus ligger på att organisationen arbetar på ett effektivt sätt. Figur 1 innehåller en graf som visar antal skrivna felrapporter över tiden. Lutningen på kurvan kan tolkas som felupptäckarintensitet, dvs hur effektiv är organisationen på att hitta fel vid varje tidpunkt.

Eftersom lutningen på kurvan är ganska brant vid tidpunkten t1, talar allt för att om testprojektet får fortgå så kommer man att hitta fler fel. Vid tidpunkten t2 verkar det som testarna inte längre hittar så många fel, vilket innebär att man antingen bör byta teststrategi eller avbryta testningen eftersom denna inte längre är kostnadseffektiv – mot det uttalade syftet. Grafen i figur 1 är alltså lämplig att använda som bas för rapportering då syftet är att stödja kvaliteten.

Figur 1. Antal skrivna felrapporter över tiden

Om syftet däremot är att mäta kvalitet så behöver man rapportera både test- och produktkvalitet, som angivits ovan. Testkvaliteten bygger på att man exekverar ett antal testfall som ska täcka en eller flera aspekter av produkten. Det går vanligtvis att göra en uppskattning av hur många testfall som kommer att krävas och därmed kan man redan i en plan beskriva en tänkt progress i termer av exekverade testfall. Figur 2 visar en sådan planerad progress samt den verkliga progressen i form av antal exekverade testfall och av dessa hur många som blivit godkända. Ur denna graf kan man (1) utläsa om testprojektet ligger i fas, d.v.s. om det är troligt att man kommer att hinna uppnå den i förväg bestämda täckningen, (2) om man inte ligger i fas, uppskatta den totala förseningen, (3) se hur kvaliteten på produkten utvecklas mot en formulerad målkvalitet som innebär att avståndet mellan kurvorna (antal exekverade resp. godkända testfall) är tillräckligt litet. Denna graf är alltså ett bra verktyg när syftet med testningen är att mäta kvalitet. Observera dock att storheten på y-axeln, antal testfall, bara får användas om man vet att det antal testfall man avser att köra verkligen uppnår den täckning man strävar efter.

Figur 2. Antal planerade, körda och godkända testfall över tiden.

Exempel 3: Åtgärder vid försening

Under en testprocessutvärdering av ett företag stötte jag på en situation i vilket ett projekt blivit rejält försenat under utvecklingsfasen. I ett försökt att minska förseningen hade man beslutat att starta den funktionella systemtestningen innan integrationen var helt färdig, vilket visade sig fungera ganska bra. Trots att testobjektet vid startpunkten för den funktionella systemtestningen hade lägre kvalitet än man räknat med vid planeringen så genomfördes denna testning i stort sett enligt plan. Man hittade visserligen fler fel än beräknat men det påverkade inte tidsåtgången i nämnvärd omfattning. Stärkta av detta valde man att även starta den icke-funktionella systemtestningen tidigare än ursprungligen planerat, d.v.s. innan funktionstestningen var helt färdig. Tyvärr visade det sig att resultatet här var precis det motsatta – den tidsåtgång man ursprungligen planerat för blev mer än fördubblad.

En stor orsak till dessa, till synes motsägelsefulla, resultat finns att hämta i de syften som företaget hade med funktionell respektive icke-funktionell systemtestning. Till att börja med ska sägas att syftena inte var uttalade utan ”fanns i väggarna”, vilket säkert gjorde det svårare att inse orsakssambanden. När vi skrapat lite på ytan framträdde en bild av att den funktionella systemtestningens primära syfte var att stödja kvalitet (hitta fel) medan den icke-funktionella systemtestningens primära syfte var att mäta kvaliteten (utvärdera systemets egenskaper). Konsekvensen av denna skillnad i syften var att för den funktionella systemtestningen spelade inte produktkvaliteten vid starttidpunkten så stor roll. Man skulle ju i alla fall leta efter fel och hela testupplägget var byggt för att hittade fel skulle rapporteras, åtgärdas och testas om i senare versioner. För den icke-funktionella systemtestningen däremot var produktkvaliteten vid starttidpunkten kritisk. Den låga produktkvaliteten gjorde att testfall som använts för att mäta någon kvalitetsegenskap (t.ex. prestanda) ideligen måste göras om eftersom hittade fel i den fortfarande pågående funktionstestningen resulterade i omleveranser av mjukvaran vilket annullerade de redan utförda kvalitetsmätningarna. Det visade sig i slutändan att vart enda icke-funktionellt testfall som exekverats innan funktionstestningen var avslutad behövde köras om vid senare tillfällen, d.v.s., i stort sett allt jobb i den icke-funktionella systemtestningen innan funktionstestningen var avslutad var förgäves.

Förutom behovet att uttala syftet med testningen drog detta företag även lärdomen att införa startkriterier för sina testfaser och att dessa startkriterier behöver vara kopplade till testningen syfte. Till exempel beslutade man att startkriterierna för den funktionella systemtestningen bland annat skulle utgöras av ett s.k. ”smoke test” bestående av ett litet fåtal centrala testfall som i princip gick ut på att mjukvara kunde installeras och startas. Motsvarande startkriterier för den icke-funktionella systemtestningen baserades på helhetsresultat från den funktionella systemtestningen i kombination med att antalet kända fel måste ligga under en viss given nivå.

Olika testsyften i olika testfaser

Ett vanligt projektupplägg är att ha flera olika testfaser, t.ex. komponenttestning, integrationstesting, systemtestning och acceptanstestning. I sådana lägen är det ofta en god ide att låta de olika faserna ha sinsemellan olika syften. På så sätt kan man låta testningen i de olika faserna komplettera varandra, gärna via en gemensam teststrategi som beskriver organisationens olika testfaser i det generella fallet. Teststrategin kan då för varje testfas beskriva; syfte, lämpliga målformuleringar, startkriterier, mätetal och rapporteringsmallar.

En annan viktig poäng med en teststrategi är att detta dokument håller samman alla testfaser och kan säkerställa att testningen som helhet får det önskvärda fokuset genom att synkronisera de olika testfaserna.

Sammanfattning

Testning kan ha flera olika syften. Det valda syftet med en viss testaktivitet kommer att påverka val av testfall, tidsåtgång och möjligheter att agera vid t.ex. försening. Syftet påverkar även formulering av startkriterier. Därför är det viktigt att man (1) Förstår vilka olika syften som kan finnas med testning, (2) Uttalar syftet med varje testfas, (3) Väljer rätt syfte(n) för rätt testfas och (4) Låter syftet influera de aktiviteter man sedan utför inom testfasen.

About Mats Grindal

Mats Grindal
AddQ

Mats Grindal har arbetat som konsult i testbranschen i närmare 20 år. Under tiden som konsult har han haft en lång rad uppdrag som spänner från testare, via testledare till test strateg, mentor och lärare. Han har även hunnit med att avlägga en doktorsexamen inom testning av mjukvara vid Linköpings Universitet.