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 över 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 ifrå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 allt fö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 ”Testdesign – Att ta fram bra testfall” där vi med hjälp av praktiska exempel går igenom hur du skriver kostnadseffektiva testfall.
Bra artikel med viktiga frågor man bör ställa.
En av de största fördelarna med enradingar är att de går mycket snabbare att granska för allehanda intressenter, och även möjliggör att se helheten och därmed vad som saknas.
Det är även lättare att ta med oortodoxa och “ständigt pågående” testidéer.
Exemplet var kanske inte det bästa, eftersom det snarare var 9 rader.
Enradingar för samma funktionalitet kan skrivas:
1 Verifiera inloggning med giltiga konton (använd testkonton.txt)
2 Verifiera bra felmeddelanden vid ogiltig inloggning (fel konto, fel lösenord, tomt, raderat konto, ändrat lösenord)
3 Verifiera att det går fort att logga in med mus och tangentbord
4 Ser gränssnittet snyggt ut på olika konfigurationer (språk, High DPI m.m.)
…
På SAST VÄST Q1 berättade James Bach om sitt nuvarande uppdrag inom “Medical”. Där ska strikta FDA-krav uppfyllas, men det står ingenting om att tester ska skrivas i förväg, så lösningen är istället att dokumentera den verkliga testningen som gjorts (loggning, video.)
Tillsammans med granskade enradingar kan vi lämna det slaviska skriptföljandet, som väl känns lite väl 1900-tal?
Testfall skrivna i förväg passar nog bäst om man har en gudomlig testdesigner vars kunskap ska sippra ner till de beskedliga testexekverarna.
Men då skulle man snarare ordinera en dos ödmjukhet.
Tack för en bra artikel, Jonas!
Jag vill dela med mig av mina erfarenheter med testfall
– extremt tråkigt att skriva
– blir inaktuella 5 minuter efter man har skrivit dem
– testar man efter testfall är man begränsad i sin kreativitet och hittar färre fel
– i agila projekt har man inte tid att skriva testfall, även om man så ville
– är nästan omöjligt att förvalta dem, dvs. hålla dem uppdaterade och vid liv
Jag gick sedan över till att skriva testidéer enligt J. Bach, vilket kändes lite bättre.
Just nu jobbar jag med modellbaserade tester inom vår testautomatisering, och ritar grafer som styr dessa automatiserade tester. Jag vill modellera grafer även för våra manuella tester och dessa grafer ska ersätta testfall och testidéer i fortsättningen. En fördel blir att vi enkelt kan identifiera vilka ytterligare manuella tester vi vill automatisera. Sedan flyttar vi dessa grafdelar från den manuella grafen över till automatiseringsgrafen och scriptar tester för dem.
Grym artikel! Hoppas att allt fler förstår fördelen med att gå ifrån testfallsfascismen (= detaljerade steg-för-steg beskrivningar).