Hej!

I det här inlägget har jag tänkt beskriva hur man söker fel i kod, så kallad debugging. Att vara bra på att hitta den kodsnutt som orsakar en bugg är till stor nytta för utvecklare, det är svårt att fixa en bugg utan att ha hittat rotorsaken till att ens system beter sig felaktigt. Med en sund strategi för debugging går processen betydligt smidigare! Värt att nämna är att jag och de flesta andra på Cinnober använder utvecklingsmiljön Eclipse så inlägget är även det baserat på Eclipse verktyg för debugging.

Som utvecklare hoppar man in strax efter att en bugg blivit inrapporterad. Efter att ha läst in sig i buggrapporten har man rätt bra koll på hur man orsakar buggen. Det första jag brukar göra är att en första gång försöka återskapa felet. Då jag väl har lyckats och fått större förståelse för vad som går fel tar jag ett steg tillbaka och funderar lite, kan jag skriva ett automatiskt test som provocerar fram den här buggen? Med ett autotest redo kan man snabbt göra ändringar och se ifall de gav rätt resultat så ifall jag kan använda mig att ett sånt skriver jag det alltid. Det lönar sig i längden, speciellt med tanke på att testet är kvar även efter att du fixat buggen och ser till att du får veta om den återvänder.

Då jag väl har ett test jag kan köra för att provocera fram buggen är det dags att leta efter orsaken. I många fall har man en aning om var man ska börja, man kan exempelvis ha tillgång till en stack trace  som pekar på ett ställe där något gått fel i programkoden eller att man helt enkelt har koll på ett lämpligt område att börja söka. Om buggen exempelvis handlar om att ett loggmeddelande skrivs ut på fel sätt är det inte helt förvånande en bra idé att kika i koden som gör loggningen innan man letar någon annanstans.

Efter att ha hittat rätt ställe att kika på börjar man sätta in några brytpunkter på lämpliga ställen, kör sitt test och stegar igenom koden i jakt på skumma beteenden. Hittar man ingenting får man bredda sin sökning och fortsätta. Om det går trögt är det aldrig fel att ta en paus och ventilera sina frustrationer vid kaffebryggaren eller ta en kort promenad runt huset, så småningom ger även de trögsta buggarna med sig. 🙂

För att visa ett lite mer praktiskt exempel kan vi tänka oss detta. Vi har ett lotteriprogram som drar en vinnare utifrån en lista med registrerade konton. Just nu finns det bara två testare som finkammar systemet efter buggar, S. Hibe och J. Wise. Vi ska precis testköra lottdragningen då vi får buggrapport från Wise, pengar verkar ha försvunnit från hans konto! Mystiskt. Eftersom att Wise är precis som sitt efternamn har han beskrivit vad han gjorde precis innan pengarna försvann i en testbeskrivning, han var i färd med att sätta in mer pengar på sitt konto.

Vi börjar med att skriva två tester som uppdaterar kontobalansen.

DepositTests

Vi kör båda testerna och ser att inget utav dem går igenom, problemet är alltså inte begränsat till specifika konton utan är av ett bredare slag.

failedTests

I nästa steg vill vi kika på vad som händer i koden då den körs så vi sätter ut en brytpunkt i början utav metoden depositToAccount i klassen för kontohantering.

breakpoint

Därefter vill vi köra vårt test i debug-läge och stega igenom depositToAccount rad för rad samtidigt som vi håller koll på vilka värden de olika variablerna har. Efter inladdning har Hibes konto 1000000 i kontobalans, vilket kan ses i variabelfönstret. Testet vill nu lägga till 1234 till kontobalansen.

variabler

Vi stegar på och upptäcker utan problem den kodrad som orsakar felet, det visar sig att vi har glömt tänka på att ta med den tidigare kontobalansen då vi skriver in insättningar. Är kontobalansen noll är det inga problem men följande insättningar blir felaktiga.

bugFoundVertical

Vi fixar till kodraden och påminner oss att täcka in fler testfall med  enhetstester framöver, det är trots allt rätt pinsamt ifall något liknande skulle hända med en kund istället för att en testare upptäcker det!

Det här är såklart bara en kort introduktion och troligtvis något som de flesta som skrivit kod redan är bekanta med. Just hur svårt det är att hitta felorsaken beror till stor del på hur stort systemet du debuggar är och hur bra kunskap du själv har om det. I vissa fall kan buggen bara återskapas i väldigt specifika förhållanden eller timingfönster vilket kan vara extra jobbigt att arbeta med. Det viktiga är att ha tålamod!

Nu är det dags för helg, ha det bra!