Grått är det nya svarta

2013-11-01 Artikelbanken Test Läst 7752 gånger

Det går inte att läsa en introduktionskurs i mjukvarutest utan att stöta på begreppen ”Black-box-testning” och ”White-box-testning”. Ofta stannar det dock vid att begreppen definieras utan att någon ytterligare vägledning ges till när de olika teknikerna (eller angreppssätten) är lämpliga att använda. Traditionellt inom testbranschen finns på många ställen en distinkt uppdelning med perspektivet att white-box-testning utförs på lägre testnivåer och black-box-testning på systemtestnivån och högre. Denna artikel har som syfte att luckra upp dessa begrepp något och att diskutera för- och nackdelar med att titta in i lådan, speciellt på de testnivåer som traditionellt inte har det som praxis. 

Begrepp

Black-box-testning definieras oftast som testning som utförs utan kännedom av hur systemet som testas är uppbyggt på insidan. Systemet behandlas alltså som en svart låda och tittar bara på vilken utdata som genereras utifrån det data som skickas in. Motsatsen White-box-testning (alternativt Glasbox-testning eller Open-box-testning) är på motsvarande sätt testning som sker med full kännedom och inriktning mot systemets inre struktur – det går att se in i ”lådan”. Mellan dessa ändpunkter har också Grey-box-testning definierats för att täcka de fall där viss kännedom finns om hur systemet fungerar på insidan. Att ha viss kännedom om ett systems inre struktur är dock ett väldigt brett begrepp och kan ju innefatta allt från att ha läst och granskat källkoden till att råka veta att systemet är implementerat i Java och att det lagrar data i en databas. Som synes är detta en glidande skala och sannolikt är det få som sysslar med Black-box-testning i sin renaste form. Det är ju rimligt att anta att de flesta testare snappar upp ett och annat om hur systemet man testar är uppbyggt, om än på en väldigt grundläggande nivå.

Hinder

På systemtestnivå och högre testnivåer är det många testare och testgrupper som sällan eller aldrig använder sig av systemets uppbyggnad som stöd i sin testdesign. Det kan finnas en rad anledningar till att så är fallet, till exempel:

  • Testarnas förmåga att läsa och förstå kod är begränsad
  • Källkod och systemdokumentation är inte tillgänglig för testarna vid önskat tillfälle. Detta kan handla om att testarna helt enkelt inte har tillgång till versionshanteringssystem eller dokumentytor. Alternativt kan det vara så att källkod/dokumentation inte finns på plats då testerna ska designas.
  • Ett mer eller mindre uttalat strategiskt val har gjorts inom organisationen att testarna bara ska syssla med Black-box-testning. Alternativt så är detta inget aktivt val utan mer en inarbetad vana som ”sitter i väggarna”.

Dessa hinder är sällan oöverstigliga om en testavdelning eller du som enskild testare vill ta ett steg mot större systemförståelse. Att lära sig ett helt programmeringsspråk från grunden kan kännas som en hög tröskel att överstiga, men lyckligtvis kan du komma väldigt långt med en grundläggande förståelse för de grundläggande konstruktionerna inom det aktuella språket. Vad gäller tillgång till verktyg så har många versionshanteringssystem idag webgränssnitt som inte förutsätter extra licenser eller långa installationsprocesser eller någon upplärningstid att tala om. Resten av hindren är mer av politisk karaktär och här hänger det helt på den aktuella organisationen hur pass lätt dessa hinder är att passera. Som det kommer att visa sig nedan så finns det dock många bra argument för att övertyga relevanta nyckelpersoner om det skulle behövas.

Förbättrad testanalys och testdesign

Vad finns det då att vinna på att testarna blir mer bekanta med systemets insida?  Är det så enkelt som att bättre kodförståelse ger bättre testning? Det finns förstås inget allmänt svar på den frågan utan som vanligt beror allt på sammanhang. Här kommer dock ett försök att lista frågor som du kan få hjälp att få svar på tack vare bättre systemförståelse.

Vilka testfall är relevanta?

Om du har tillgång till källkoden när du designar dina testfall kan det vara en bra informationskälla. Vi kan till exempel tänka oss en enkel applikation som läser in stora datafiler och konverterar om dem till ett annat format. I vår tänkta källkod kan det till exempel visa sig att programmet jobbar med 1000 rader i taget av prestandaskäl. Ett värdefullt test kan då vara att jobba med filstorlekar både strax under och strax över 1000 rader. Detta är ett exempel på ett så kallat dolt gränsvärde som vi inte hade känt till om vi inte studerat systemets inre delar. Vid en närmare titt på koden (se figur nedan) visar det sig också att programmet kör olika kod för vissa typer av teckenkodning (teckenkodning är en specifikation på hur varje tecken i en fil ska uttryckas med ettor och nollor, exempel på teckenkodning är UTF-8 och ASCII).

Här ser vi att det kan vara värt att upprepa testet med olika filstorlekar kombinerat med olika teckenkodning. Samtidigt har vi lärt oss vilka typer av teckenkodning som behandlas av samma kod vilket gör att vi kan göra en rimlig avgränsning i hur många kombinationer av teckenkodning och filstorlek som behöver testas. Vi har alltså både upptäckt tester som vi kanske inte skulle ha tänkt på annars och fått hjälp med att avgränsa oss. Det är långtifrån säkert att denna typ av information skulle ha avspeglats i några krav då detta inte har med systemets funktionalitet att göra.

Testar vi det vi tror?

I många system är det inte alltid helt uppenbart hur koden du vill testa ska triggas. Detta blir speciellt aktuellt vid regressionstest då sena ändringar eller buggfixar har kommit in i redan testade delar av systemet. Tiden är ofta knapp och det gäller att på ett snabbt och effektivt sätt kunna testa av den ändring som gjorts, något som kan underlättas rejält genom att studera koden för ändringen. I ett tänkt system nedan är variablerna A, B och C parametrar för indata. Låt oss säga att en buggfix gjorts som innefattar behandlingen av variabeln A.

Om vi studerar flödet så ser vi att variabel A används bara om variabel B har värdet True. I ett rent black-box-test hade detta lätt kunnat förbises med följden att du kört en mängd tester med olika värden på A utan att någonsin trigga den ändrade koden eller bara trigga den i en delmängd av fallen. Med hjälp av en snabb kodanalys kan vi alltså spetsa till och effektivisera vår regressionstest.

Hur mycket test behövs?

Som testare behöver du ofta bedöma hur mycket testning som behövs för en given kodändring. Utan att veta speciellt mycket om koden i detalj kan du dra vissa slutsatser ifrån systemets arkitektur. Vissa moduler är mer centrala än andra och detta har stor påverkan på testscopet, det vill säga omfattningen av testerna. Ett exempel kan ses i bilden nedan där vi har en övergripande arkitekturbild på ett tänkt system.

En ändring i modul D som är väldigt central i arkitekturen riskerar potentiellt att orsaka problem i alla systemets delar då den både skickar och tar emot information från övriga delar av systemet. I kontrast kan en ändring i modul E ses som betydligt mindre riskabel då den bara tar emot information från en modul och inte skickar information till någon. Det är rimligt att anta att regressionstestinsatsen blir betydligt större för ändringar i modul D jämfört med modul E. Samma princip går också att tillämpa inom en kodmodul där ändringar av variabler eller funktioner som används på många ställen ofta medför högre risk än ändringar av mer isolerade kodstycken.

Ibland är det dock väldigt svårt att dra några pålitliga slutsatser från koden då det finns mycket kod som är oerhört komplex och svår att överblicka. Att koden är svår att dra slutsatser ifrån är dock viktig information i sig då chansen är stor att den som gjort ändringen inte heller kan överblicka alla konsekvenser. Hög komplexitet medför helt enkelt högre risk för oönskade sidoeffekter. Vill du formalisera din analys vid regressionstester kan du införa ett komplexitetsmått på alla kodmoduler. Till exempel finns det verktyg för en mängd programmeringsspråk för att räkna ut den så kallade cyklomatiska komplexiteten för en viss kodmodul. Den cyklomatiska komplexiteten ger ett värde på storleksordningen av antalet olika vägar koden kan exekveras och ger alltså en fingervisning om hur mycket testning som kan behövas. Ett mått på cyklomatisk komplexitet eller något annat komplexitetsmått kan införlivas i en riskanalys utan att direkt kodgranskning genomförs vid varje regressionstestinsats. Ett högt värde på komplexiteten ger att testinsatsen bör bli relativt omfattande. Det du vinner i snabbhet på denna kvantitativa analysvariant förlorar du dock i exakthet jämfört med att granska varje ändring kvalitativt i sitt sammanhang. Vill du inte sträcka dig så långt som formaliserade komplexitetsmått så kan enkla konstateranden som ”den här koden är väldigt svår att följa och har många beroenden, vi måste nog regressionstesta ganska mycket” vara väldigt värdefulla jämfört med att inte studera koden alls.

Informationen gällande ändringar och kodstruktur som behandlas ovan kan delvis ersättas av dialog med utvecklaren av systemet. Det är också på detta sätt som många testare och testorganisationer idag arbetar. Om ingen egen analys görs förs i bästa fall en dialog med någon på utvecklingssidan om vilka risker som de senaste ändringarna av systemet medför. Det som missas med detta arbetssätt är dels möjligheten att låta två par ögon göra riskbedömningen och dels att riskbedömningen görs av någon som inte har samma beroende från koden. Om du anser det viktigt att ha en oberoende part som testar systemet så kan det kanske också vara relevant att ha en oberoende part som medverkar i riskbedömningen av ändringar i systemet?

Mjuka värden

Att öka kvaliteten på de tester som designas och utförs är starka argument i sig. Förutom detta finns också en mängd mer mjuka faktorer som påverkas när testarna börjar sätta sig in i systemets inre delar. Dels innebär en satsning på ökad kodförståelse en kompetenshöjning hos testarna som kan bidra till att lyfta gruppen. Testarnas status på företaget kan också få sig en skjuts i rätt riktning, inte minst hos utvecklarna, vilka testarna nu kommer att kunna kommunicera lättare med tack vare att alla kan kommunicera ”på samma språk”. De testare som är insatta i koden kan också hjälpa utvecklarna med felsökning och avlusning. Ibland har testaren kanske redan under testarbetet upptäckt problem i koden och då kostar det väldigt lite att kommunicera det till utvecklaren. Ibland kan det vara så att utvecklarna är hårt belastade och då finns det möjlighet för testarna att kliva in och ta en större del av ansvaret för att ringa in problemen. Jag har i denna artikel hittills avhållit mig från att blanda in olika utvecklingsmetodiker då jag anser att bättre systemförståelse är något du har nytta av oavsett vilken utvecklingsprocess du arbetar inom. Det går dock inte att frånse att argumenten ovan går hand i hand med mycket av det som förespråkas inom lean och agil utveckling.

Fallgropar

Denna artikel har än så länge lagt fram en mängd argument för att du som testare ska ta några steg mot att bättre förstå insidan av det system du testar. Vad finns det då för baksidor och fallgropar med att grotta ned sig för långt i systemets uppbyggnad?

Tappat fokus på andra faktorer

Ju mer du som testare fokuserar på kodrader, loopar och dolda gränsvärden desto mindre tid och fokus kan du lägga på de yttre faktorerna såsom krav och kundnytta. Det finns alltså en risk att du tappar bort omvärlden och slutkunden och istället letar kluriga felfall som kanske mycket sällan skulle orsaka problem hos kunden.

Övertro på den egna analysen

De flesta mjukvarusystem idag är oerhört komplexa och det är ofta svårt att förutspå hur ändrad kod kan påverka andra delar av systemet. Har du som testare granskat en ”trivial” ändring, kan du ha svårare att motivera dig att utföra till synes onödiga regressionstester. Att börja hoppa över säkerhetskollen som några grundläggande smoketester kan utgöra kan visa sig vara en farlig väg att vandra. För att undvika detta kan du skapa en testidélista på vad du skulle vilja testa innan du ger dig på att studera koden, och på så sätt undviker du att färgas för mycket av din kodförståelse.

Sammanfattning

I tabellen nedan sammanställs för- och nackdelar med liten och stor systemkännedom så som de har tagits upp tidigare i artikeln.

  Mindre systemkännedom Mer systemkännedom
Fördelar
  • Fullt oberoende mot kod gör det lättare att kritiskt granska systemet utifrån krav- och kundperspektiv.
  • Bättre möjlighet att göra bra testdesign som täcker viktiga fall och motionerar den kod som ändrats.
  • Större chans att testinsatsen blir rimligt stor givet gjorda ändringar.
  • Lättare för testarna att kommunicera med utvecklare.
  • Testarna kan hjälpa till med felsökning och avlusning när belastningen är hög på utvecklarna.
Nackdelar
  • Svårare att veta vilken kod som testas.
  • Svårt att dimensionera testinsatsen givet vilka ändringar som gjorts.
  • Mer beroende av utvecklarna för riskanalys.
  • Mindre flexibilitet vid ojämn arbetsbelastning.
  • Risk att användarperspektivet tappar i betydelse.
  • Risk att tappa oberoendet mot koden och överskatta förmågan att förutse sidoeffekter.

Sammanfattningsvis kan sägas att hur systemet du testar är uppbyggt på insidan är en av flera viktiga pusselbitar i det stora testpusslet som du behöver lägga. Denna information bör förstås balanseras mot all annan information du tillgodogör dig under en utvecklingsaktivitet, såsom krav och kundkännedom. Men som testare behöver du alltså inte vara rädd för att titta in på insidan i lådan, det är sällan en dålig idé. Verkligheten är ju, till skillnad från den berömda lådan, varken svart eller vit. Se bara till att inte krypa in för långt, för det är svårt att hålla koll på omvärlden där inifrån.

Nästa steg

För att ytterligare stärka ditt testarbete rekommenderar vi att du även läser Utmaningar med systemintegrationstest, Rätt testdata – hur man hanterar den ”glömda” dimensionen samt Automatiserad integrationstestning är din bästa plåga som du alla hittar här i Faktabanken. Vi vill också rekommendera att du funderar på en kurs i testdesign exempelvis Agil Test.

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