Bättre testdesign ger lägre kostnader

2010-02-19 Artikelbanken Test Läst 16557 gånger

Traditionellt sett är testdesign i mångt och mycket förknippat med framtagandet av testfall som innehåller detaljerade steg-för-steg beskrivningar av vad som skall utföras under testerna. Dessa testfall är ofta skrivna på en sådan nivå att ”någon direkt från gatan” skall kunna följa dem och utföra testerna.

Om vi nu, med handen på hjärtat tänker efter, hur ofta tar vi i praktiken in ”någon direkt från gatan” för att köra våra testfall? I de fall vi faktiskt tar in en utomstående för att testa vår applikation så är det oftast med syftet att studera hur en oinvigd spontant använder applikationen. Denna spontanitet skulle gå helt förlorad om vi satte steg-för-steg testfall i händerna på denna någon från gatan.

Överdokumenterade testfall – Onödiga kostnader

Denna kvarleva att överdokumentera testfallen resulterar i en rad oönskade effekter. Till att börja med så tar det lång tid att skriva all textmassa, för att inte tala om hur tråkigt det är. För det andra så är det nästan omöjligt att hålla dessa detaljerade beskrivningar uppdaterade när applikationen förändras, vilket resulterar i att testfallen skrivs om inför varje testomgång. Och slutligen den kanske största nackdelen, du kan inte skriva klart dina testfall innan du sett applikationen. Detta leder till längre testperioder och därmed långsammare återkoppling till både utvecklare och beställare.

Sammantaget innebär detta långsammare utvecklingscykler, tråkigare arbete och framförallt onödiga kostnader. Det som är positivt med detta är att vi med några enkla tekniker och angreppsätt kan eliminera dessa negativa effekter.

Bättre Testdesign – Att ta fram kostnadseffektiva testfall

Hur gör vi då för att undvika att hamna i fällan med kostsamma, överdokumenterade, icke återanvändbara testfall? Vi börjar med att ställa några relevanta frågor om applikationen vi testar:

  • Kommer applikationen att vidareutvecklas under en lång tid?
  • Skall applikationen leva länge?
  • Finns det något i applikationen som regleras av lagar och förordningar?

Vi behöver även fundera runt några frågor om vår organisation,

  • Är det oerfarna testare som skall exekvera testerna?
  • Kommer nya personer att utföra testerna varje gång?
  • Är vi mogna att testautomatisera våra regressionstester?

Svarar vi nej på samtliga av ovanstående frågor så är det effektivaste att helt hoppa över framtagandet av traditionella testfall och istället använda sig av angreppsätten utforskande test och test mot checklistor. Detta då dessa angreppsätt är effektiva på att hitta många fel till låg kostnad, men de kräver i gengäld erfarna testare då vägledning i form av testfall saknas. Det är även svårt att på ett identiskt sätt återupprepa testerna. Detta gör dem olämpliga att använda för regressionstest eller där fullständig spårbarhet och dokumentation av testerna krävs.

Om vi däremot svarar ja på en eller flera av frågorna i ovanstående frågeställningar om applikationen och organisationen så är det värt att funderar över hur många, långa och detaljerade testfall vi bör ha för att vara så kostnadseffektiva som möjligt. Grundregeln är att inte detaljera ett testfall mer än absolut nödvändigt samt att hellre dela upp i många korta än skriva några få långa testfall. Vad som är absolut nödvändigt varierar förstås från fall till fall men man skall aldrig skriva mera detaljerade beskrivningar än vad som krävs för att den tänkta målgruppen skall kunna utföra testet.

”En-radingar”

På de områden i applikationen som inte på grund av tekniska eller juridiska skäl kräver detaljdokumenterade steg-för-stegtestfall så rekommenderar jag starkt att ni provar att använda er av så kallade ”en-radingar”. Det är testfall som på en rad beskriver det som skall utföras i testet. Denna korta beskrivning skall vara formulerad så att även syftet med testfallet framgår. Som exempel kan vi ta inloggningen till testverktyget ReQtest.

Skillnaden mellan ett traditionellt testfall och en ”en-rading” syns tydligt om vi studerar ett konkret exempel. I exemplet nedan har vi tagit fram ett traditionellt testfall samt en ”en-rading”, båda med syftet att testa inloggningen till webbapplikationen ReQtest med ett giltigt aktivt konto.

Redan i detta mycket triviala exempel så ser vi att det traditionella testfallet mycket snabbt skulle bli föråldrat och därmed kräva underhåll. Det begränsar även testerna till ett specifikt konto vilket gör att testtäckningen blir mycket smal och många testfall behöver skrivas för att täcka alla varianter av användarnamn och lösenord. Det är även svårt att använda detta testfall som ett generellt inloggnings-testfall som kan återanvändas i flera testscenarion, då det specifika valet av testkonto gör det alltför specifikt.

”En-radingen” kräver att vi förstår hur applikationen fungerar och var den finns, men är å andra sidan underhållsfritt och begränsar inte testet till ett specifikt konto. En erfaren testare verifierar i detta fall olika typer av användarnamn och lösenord utan att ytterligare testfall behöver skrivas. ”En-radingen” skulle dessutom kunna skrivas långt innan vi vet hur gränssnittet faktiskt ser ut. Denna variant kan även återanvändas i alla testsenarion som kräver inloggning.

När detaljerade testfall måste användas

Det finns givetvis situationer när det inte lämpar sig med enbart ”en-radingar”. Några exempel på när det ofta krävs steg-för-steg testfall är när vi testar komplexa beräkningar, komplicerade flöden eller specifika kombinationer.

Det kan även krävas repeterbara detaljerade steg-för-steg instruktioner om det är komplext och tidsödande att ta fram ny testdata. Detta gäller i synnerlighet om testdatat är starkt beroende av flödet. Samma sak gäller om det förväntade resultatet är svårt att beräkna fram för olika indata eller om det förväntade resultatet är stark flödesberoende.

Minska förvaltningskostnaden för detaljerade testfall

Även då det krävs någon form av detaljerad steg-för-steg beskrivning i testfallen så finns det mycket man kan göra för att minska testfallens förvaltningskostnad. Nedan följer några exempel på detta.

Minska detaljeringsgraden på beskrivningen till varje steg i testfallet

Även om vi måste skriva steg-för-steg beskrivningar så kan vi välja deltaljeringsnivån på varje steg. Det gör vi efter samma principer som vi diskuterat för hela testfall tidigare.

Grundregeln är att inte detaljera varje steg mer än absolut nödvändigt utan att hellre dela upp i många steg med korta instruktioner än att skriva några få steg med långa instruktioner på varje steg. Med absolut nödvändig menas i detta fall att det skall framgå vad som skall göras, inte exakt hur det skall göras.

Hårdkoda inte testdatat i testfallet

Hårdkoda inte testdatat i testfallet då det då inte går att återanvända på ett smidigt sätt. Ersätt det istället med en referens till separat testdata-dokumentation i form av en parameter. När vi använder oss av parametrisering blir det även lättare att återanvända testfallet med många olika varianter av testdata.

I exemplet nedan så ser du hur vi i det första testfallet hårdkodat in kontouppgifter och förväntat resultatet i testfallet, där vi i de nästkommande testfallen refererar till ett separat testdata-dokumentet Testkonton.txt med hjälp av parametrarna <<TestKonton_ValidaKonton>> och <<TestKonton_FelaktigtKonton>>.

För att underlätta återanvändning mellan projekt och överlämning till förvaltning så är det viktigt att beskriva önskade egenskaper för testdatat snarare än specifika värden. Detta gäller även när vi använder oss av parametrisering.

Bygg upp dina testfall modulärt för att sänka förvaltningskostnaden

Det är även viktigt att tänka på hur du strukturerar och delar upp dina testfall för att få dem så återanvändbara som möjligt. Om vi till exempel skall skriva testfall för att testa av följande flöde

så väjer vi att skriva ett testfall för varje funktion, snarare än att skriva ett testfall som testar av hela flödet. Om vi sedan vill testa av hela flödet så knyter vi helt enkelt ihop de olika testfallen till ett testscenario. På så sätt kan vi återanvända samma testfall även om flödet ändrar sig utan vi knyter bara samman dem till ett nytt scenario som speglar det nya flödet. Denna uppdelning är även effektiv att tillämpa på ”en-radingar”.

En annan vinst vi får om vi funktionsuppdelar våra testfall är att vi bara behöver ändra på ett testfall när t.ex. ”Välj Vara”-funktionaliteten ändrar sig. Hade vi inte funktionsuppdelat testfallen så hade vi behövt ändra i samtliga testfall som berörde ”Välj Vara”-funktionaliteten.

Funktionsuppdelade testfall minskar alltså behovet av underhåll och omskrivning av dina testfall och detta ger sänkta förvaltningskostnader.

Sammanfattning

Nyckeln till en lyckad testdesign är kostnadseffektiva och återanvändningsbara testfall. Detta uppnår du genom att skriva modulära testfall med en detaljeringsgrad som är anpassad efter situationen. Eller med andra ord, ge inte mera information än vad som krävs för att utföra testet och undvik att hårdkoda testdatat.

Nästa steg

Konsultbolag1 erbjuder kursen Agil test där vi med hjälp av praktiska exempel går igenom hur du skriver kostnadseffektiva testfall.

KONTAKTA OSS

Har du frågor? Vill du ha hjälp med områden inom kravhantering och test?
Hör av dig till oss! Vi hjälper dig gärna. 

Kontakt 

Dela artikeln