Learning by failing

För en tid sedan testade jag en funktion för att publicera och läsa annonser. En ganska ordinär funktion. Ett formulär för att skapa annonser, en sida för att hantera/administrera dem och en sida för att läsa, sök och filtrera bland skapade annonser.

Efter lite buggrättningar och fixar publicerades funktionen i testmiljön och såg ut att fungera som förväntat. Annonser kunde skapas och läsas, updateras och raderas utan problem. En funktion tog några timmars testande och sedan var det dags att gå vidare.

Jag hade missat en grej.

Dagen efter mina tester var samtliga annonser borta. Ingen hade rört något förutom en ‘någon’; webcrawlern.
Det visade sig att länken på administrationssidan för att radera en annons var just en länk, webcrawlern är programmerad att följa länkar.

Vad jag missade i mina tester var ett livstidstest; vilka faktorer kommer att påverka annonsen under hela dess livstid?
Nu kanske jag har lärt mig.

Komplexitetstrender

Nyligen diskuterade vi trender inom den digitala kommunikationen här på kontoret. Många av de presenterade trendspaningarna rörde den mobila webben, mobile enheter och multipla skärmar. Vår närhet blir mer mobil och användare förväntar sig hitta tjänster varthelst där finns webb-access, vilket förväntas vara i stort sett överallt. Det är inte längre bara så kallade smartphones som ska övervägas längre, det finns tablets, tv:n börjar bli uppkopplad, till och med kylskåp har internet-access och kan mycket väl vara en platsform för vissa företags digitala närvaro.

Det här är en växande utmaning för testavdelningen. Det går inte längre bara att fokusera på plattformen Windows/Internet Explorer när man utvecklar webbtjänster. Redan som det är nu har jag svårt att hänga med i utvecklingen av mobila enheter och plattformar.

Ju fler plattformar som tas med i beräkningen desto dyrare blir utveckling och inte minst test. Testhårdvara är bara en del av det; hur håller man sin maskinpark modern och samtidigt håller ner kostnaderna för underhåll? Hur fokuserar man testerna till rätt plattformar.

Dessa nya plattformar och enheter ökar behovet av att i test separera data och presentation. Datahantering, back-end -logik, testas separat och kanske läggs till och med huvuddelen av testerna på presentation och front-end-logik.

Att lägga mer fokus på front-end-logik blir också mer och mer aktuellt på grund av dess skörhet. Back-end-kod är ofta, i min erfarenhet, väl understödd av ramverk och språkstandarder varför fel i koden är, om inte ovanliga, så i alla fall ganska väl hanterade, medan presentationskoden kan dras med en del manuella fel.

CSS är också kod

Det är lätt att som testare lägga värderingar i olika typer av buggar. En bugg som är svårare att hitta är mer värd än en som är lätt att hitta, eller snarare; buggar som man inte behöver lägga ner så mycket energi på att hitta är mindre värda än de man jobbat hårt för att hitta.

Jag vet själv att mina favoritbuggar tenderar vara sådana som jag fått leta efter ordentligt. Det är inte underligt att det är så eftersom man kommer ihåg den belönande känslan av att lägga ner arbete, komma förbi utmaningar och få utdelning, att bevisa att man minsann kan och är duktig. Att se något som verkar uppenbart är inte lika tillfredsställande, lite som att vinna en tävling där man är den enda tävlande, medaljen smakar liksom inte riktigt guld.

Dessvärre motsvarar värderingarna man själv har inte alltid de värderingar som är viktiga för ett projekt. Det kan ofta vara slöseri med tid, ur projektets synvinkel då, att gräva efter den fräckaste buggen. Projektet vinner mer på att de uppenbara buggarna rättas till. Genomslaget för de mest svårfångade buggarna hade i många fall varit i stort sett noll, någon ynka del av en procent av användarna hade kanske påverkats.

Besökare på en webbsida möts först och främst av presentationslagret, CSS och Javaskript. Buggar i någon av dessa kan ha väldigt mycket större genomslag än en undflyende bugg i bakgrundslogiken.

Användarcentrerat

En flytt gav mig anledning att som “riktig” användare besöka ett par webbsidor tillhörande företag som levererar livsnödvändiga funktioner till en modern man; internetleverantör, elleverantör och transportbolag.

Nyfiken på vilka nya fräcka funktioner och interaktionsmodeller de här bolagen utvecklat för att effektivisera sin kundtjänst satte jag igång, inte för att testa utan för att bländas av hur jag håvas in i bolagens trygga kundfamn. Hade jag fel eller?!

Internetleverantörens sida tog hem priset som sämst, men det var med en hårsmån, de andra var inte långt efter. Jag var till slut tvungen att finna mig i 30 minuters telefonkö för att kunna göra en enkel beställning som sedan visade sig ta 3 veckor att leverera!

Min topplista över buggar i formulär man presenterar för användare ser ut som följer.

1. Ingen vägledning
Det är elakt att låta användaren prova sig fram till vad man ska fylla i ett visst fält, och dessutom inte ge någon feedback innan hela formuläret är ifyllt och skickat. Ett klassiskt exempel, som verkar vara svårt att få till, är personnummerfälten. Personnummer borde inte vara så svåra att vägleda till men jag har åtskilliga gånger svurit över att mitt personnummer inte vill accepteras bara för att efter tre försök förstå att det ska vara ett mellanslag innan de fyra sista, inte ett streck.

2. Önskad information får inte plats
Ett fält som ska ta emot specifik data måste kunna ta emot den efterfrågade informationen. I mina desperata försök att beställa internetaccess efterfrågades bland annat ett lägenhetsnummer. Numret jag hade var 8 siffror men fältet där de skulle in tog bara emot 7! Mitt nummer fanns helt korrekt i databasen, och visades även upp på sidan.

3. Felmeddelande utan relevant information
Efter att ett formulär har försökts att skickas får man informationen om att något gick fel och information saknas eller inte är korrekt ifylld. Det är ju ok, det kan man ju komplettera om man fick veta vilken information som saknades eller var fel. Kombinera gärna med saknade obligatorisk markingar och punkt 4.

4. Ifylld information sparas inte.
Det är alltid med hjärtat i halsgropen man navigerar till nästa steg i formuläret, kommer informationen att finnas kvar om något går fel? Man tror gärna att det här problemet inte förkommer efter 2006 men så är tydligen inte fallet. Kombineras gärna med punkt 1 för bästa effekt.

5. Slutgilitgt fel
Ett av de mest frustrerande felen är när man lagt ner en massa tid och energi på att fyllai ett formulär på helst flera sidor och när man slutligen skickar inte det får man bara felmeddelandet att “Din förfrågan kunde inte behandlas. Systemet är nere för tillfället, försök igen senare”. För en riktigt välriktad spark i skrevet kombineras denna med punkt 4 ovan.

Jag lovar att inga formulär jag varit med och testat under utveckling kommer ha något av dessa fel.

Hittat under letande

Rikard Edgren använder ofta det engelska/amerikanska ordet “serendipity” för att peka på en viktig egenskap hos testare. Ordet betyder något i stil med att upptäcka saker utanför det fokuserade.

Alldeles nyligen träffade jag på ett bra exempel där jag uppmärksammade en nyhetslista som var helt tom. Det är inte ovanligt att nyhetslistor är tomma i testdata, nyheterna kan ha plockats bort eller listan kan vara uppsatt helt felaktigt, men i det här fallet var det något som fångade min uppmärksamhet. Egentligen hade inte testuppslaget jag jobbade med inte alls med nyheter eller nyhetslistan att göra, utan bara råkade handla om samma sida.

Jag började så smått titta på varför inte nyhetslistan visades och ju mer jag grävde i hålet desto större blev stenen. Till slut var det inte mycket annat att göra än att lämna en ofärdig felrapport vidare till utvecklaren med intentionen att diskutera den vid första bästa tillfälle.

När jag sedan frågade utvecklaren om buggen fick jag hjälp med en hel del letande bland indexeringar och databaser och det visade det sig att det var på grund av en bugg i tidsstämplingen som inte innehållet visades. En bugg som hade påverkat avsevärt mycket mer än nyhetslistan hade den fått gå ouppmärksammad.

Kan jag då vara nöjd över att ha hittat buggen, det var ju bara en ren slump?

Jo, det må vara en slump att felet visade sig på just den sida jag just då tittade men fortfarande krävs det erfarenhet och övning, inte minst i den aktuella lösningen, för att se som testare vara uppmärksamma en sådan sak. Dessutom krävs det nyfikenhet i att flera timmar fortsätta gräva efter anledningen till varför det inte fungerar, något som är lätt att förlora när man lämnat visare till t.ex. utvecklaren. I det här fallet krävdes det faktiskt en viss nyfikenhet från annan part för att verkligen hitta felkällan.

Så var det slump? Ja.
Tur? Ja.
Testarskills? Ja!

Falsk positiv

Ett fel jag stöter på hela tiden nnär jag tittar på mina äldre selenium-tester är falska positiver. Det handlar om verifieringspunkter som inte alls tillför något värde utan kommer att släppa igenom nästan vad som helst utan att ge fel.

Vanligast är det att dessa punkter uppstår vid användandet av metoden IsFalse(bool expr) som alltså ger ett felmeddelande om expr skulle vara sant, dvs true. Det verkar ju jättebra om man vill kontrollera att någonting inte visas på en sida, men ackså lätt det är att använda det på fel sätt!

Att någonting inte visas är mer regel än undantag; det finns förmodligen hundratals fall där det inte visas och ett där det visas. Det ger ju i sin tur effekten att expr i stort sett alltid kommer vara falsk, false, och testfallet kommer ge gröna staplar.

Exempel:
Ett klassiskt scenarie, logga in. Här vill jag kontrollera att inloggningen lyckas och alltså att inget felmeddelande visas:

selenium.Type(username, "css=#username");
selenium.Type(password, "css=#pass");
selenium.Click("css=#submit");
assert.isFalse(selenium.IsElementPresent("css=.applications #error"),
   "Hittade ett felmeddelande. Login fungerade inte.\n");

Om klassen “application” byter namn av någon anledning så kommer den här kontrollen alltid att vara false, dvs ge en grön stapel i testfallet, även om det eftersökta error-elementet visas.

Så mitt tips är väl egentligen att vara restriktiv med att kontrollera att saker inte finns och att i de fall man måste göra det kombinera med flera kontroller som validerar den kontrollen. I exemplet vet jag att om felet visas så kommer jag inte gå vidare till startsidan som förväntat vilket i så fall är en bättre kontroll:

selenium.Type(username, "css=#username");
selenium.Type(password, "css=#pass");
selenium.Click("css=#submit");
assert.isTrue(selenium.IsElementPresent("css=.start-page"),
   "Startsidan visas inte. Fallerade loginförsöket?\n");

Testspel

Fast på nivå 26 av 38 i det mycket utmanande Android-spelet “Impossible level game” känner jag mig redo att ge upp och börjar fråga andra runt omkring mig om de har några idéer. En utvecklare blir lite intresserad och tar telefonen, efter mindre än 3 minuter har han avancerat till nivå 27. Jag blev både lättad och lite besvärad efter 3 veckor av funderande och testande i försök att ta mig vidare. Nivån i sig består bara av en färgglad sida med text som proklamerar att nivån verkligen är omöjlig och att jag borde ge upp, en riktig Gordisk knut.

Mitt laterala tänkande, som hela spelet bygger på att träna, handikappades av hur tidigare nivåer lösts. Hur jag än vände och vred på problemet, och tro mig när jag säger att vissa försök skäms jag för, lyckades jag inte hitta någon ny infallsvinkel. Min modell av spelet saknade dock en variabel visade det sig, och jag hade inte märkt det, jag hade helt enkelt drabbats av hemmablindhet.

Det lustiga är att så snart utvecklaren löst problemet, utan att berätta hur, så löste jag det också på 1 min!

Samma sak händer ofta när jag testar, jag fastnar i en modell och lyckas inte vända ut och in på den ordentligt. Delvis beror det på tidspress, en form av “good enough”-mentalitet infinner sig och jag har inte tid att som i spelet gå och klura eller passivt fundera på det i flera dagar, och delvis på grund av att jag har mycket kvar att lära inom lateralt tänkande.

På samma sätt kan man också använda andra personer för att komma vidare i testerna av en funktion. Det kan räcka med att snabbt diskutera funktionen med någon, att berätta om den. Beskrivandet i sig kan ta mig ur hålet jag fastnat i, men jag kan även få inspiration och direkta idéer av personen.

Det är som partestning där partnern inte vet om att han är med och genererar testidéer!

Restless testing

I flera bloggar och många historier jag hört handlar intressanta buggar om fel som upptäckts av en händelse. Det händer mig också väldigt ofta att jag med ett vaket öga stöter på en konstighet där jag inte alls förväntat mig det, där mitt aktuella testfall inte var riktat. En intressant bugg hörde jag berättas om idag som fick mig att tänka på användarbeteende som grund för sin testdesign.

En svensk medelstor bank hade i ett system en knapp för att makulera en betalning. Tryckte man på knappen betalades pengarna inte ut utan gick tillbaka till ägaren. De flesta vet att en knapp är någonting man trycker på en gång för att få en reaktion. Dessvärre, eller hur man ska uttrycka sig, finns det även användare som inte är så datorvana och en gång har lärt sig dubbelklickadet är händelsernas frälsning och därmed dubbelklickar på allt som ser klickvänligt ut.

I det här fallet visade det sig att varje klick på knappen resulterade i en makulering. Användare som dubbelklickade lyckades alltså få tillbaka dubbelt så mycket pengar som de som enkelklickade, betalningen makulerades och fördes tillbaka till kontot två gånger. För banken är det en katastrof!

Så hur hade man designat ett testfall för detta?

Genom att ha sett sin gamla farmor dubbelklicka loss på allt som muspekaren landade på skulle man kunna ha identifierat en användargrupp som hade ett visst beteende. Men det är inte så många som skulle kommit på idén i en testsituation om man inte haft tekniken klar för sig i någon form av kom-ihåg-listsa. Jag har lagt till tekniken till min lista och vill kalla den restless testing; testaren klickar i frenetiskt på allt som finns på skärmen. Jag har läst flera exempel på hur detta beteende framkallat buggar när testaren hamnat i något segt system och i frustration och rastlöshet börjat klicka på saker och PLOPP så visar det sig att systemet inte kan hantera sådan beteende.

Buggen fanns förståss inte i knappens implementation utan i systemets “back end”. En makulering ska såklart inte kunna utföras två gånger utan att någon kontroll görs om överföringen fortfarande finns tillgänglig, inte blivit makulerad redan.

Swedish Workshop on Exploratory Testing

För ett par veckor sedan deltog jag i SWET, Swedish Workshop on Exploratory Testing, en så kallad peer conference. En upplevelse. 14 deltagare från Sveriges testscen och en från Amerika, James Bach.

Upplägget på peer conferences är i stora drag att så många som möjligt berättar kortfattat om en erfarenhet inom området och sedan blir det frågestund. Mer om hur det går till kan läsas hos Thoughts from the test eye.

Vad som blev tydligt var hur svårt det verkar vara att införa sessionsbaserad testledning (sbtm), vilket är en bra behållare för utforskande tester, i lite större organisationer. Det vara lite av en ögonöppnare för mig som inte har erfarenhet från någon sådan organisation utan alltid har hamnat i situationer där förändring har uppskattats men framför allt där testorganisationen har fått stå för sig själv. Utan en ledning som ställer krav på hur man ska arbeta eller på att man ska leverera siffror för att beskriva hur det går hamnar man inte i samma fälla med att vara tvingad att jobba på ett sätt man egentligen vet är fel. Det var intressant att få höra hur man gått till väga för att försöka införa arbetssättet.

Något nytt jag lärde mig var avrapportering med hjälp av PROOF, en akronym jag missat helt säkert beroende på att jag inte använt mig av sbtm i någon större utsträckning, testledning över sig själv kräver inte det verktyget. Henrik Andersson hade ett tillägg för att stävja att grupper slutade göra ordentliga avrapporteringar när känslan spred sig att nyttan med dem var avtagande. De två bokstäverna i tillägget var LA och fokuserade på testaren snarare är testningen, en tanke jag verkligen gillade. Mina paralleller drogs litegrann till SCRUM:ets retrospective som jag tycker tenderar, i mina projekt, att stagnera. Hur man skulle kunna använda bokstäverna är jag inte säker på men det fick mig att tänka på hur man skulle kunna se till att stävja den förmodade dåliga vanan att utelämna detta möte. Mer om det senare förmodligen…

Sedan höll James låda kring trådbaserad testledning. Det var en intressant historia och idén är bra, om än inte ny. Framför allt är det bra att man tar upp det som ett medvetet arbetssätt, något som många redan sysslar med men inte tänkt på kan vara till nytta för andra. Om man nu har ett namn kan man börja utbyta erfarenheter kring hur man använder det.

Mest givande var, som förväntat, den mer avslappnade diskussionen som pågick i poolen med en öl i handen lite senare på kvällen. Det är alltid roligt att prata med folk som är intresserade. Bland annat dryftades TestZonens förfall.

Allt som allt en väldigt spännande sammankomst ur vilken jag kommit med en hel del nya erfarenheter, kunskap och uppslag.

Mer om händelsen kan man läsa hos:

SAST 15 år

Två dagar med föreläsningar och diskussioner om test avklarade och visst var det ett bra arrangemang! Dessvärre levde inte föreläsningarna upp till förväntningarna.

Programmet för tillställningen lovade gott. 5 olika spår med föreläsningar, vad spåren inriktades på var inte helt klart förutom spår 5 som verkade vara dedikerat till sponsorerna. Många av föreläsningarnas titel innehöll ordet agil eller dess engelska motsvarighet agile, vilket såklart är ett hett ämne och jag kan tycka att det borde finnas många lärdommar att ta del av. Men i vanlig ordning lyckas ingen leverera något nytt. Det är samma generella slutsatser och inga erfarenhetsberättelser. Självklart fanns det säkert en del godbitar, som jag hörde talas om, men tyvärr verkar det som att jag valde fel.

Pablo Garcia höll en låda om hur en undersökning, utförd ovetenskapligt internt på företaget, hade kommit fram till de fem viktigaste tipsen för att klara sig i agila projekt. Resultatet sjablades bort fullständigt, men resan dit var åtmindstone underhållande att lyssna på.

AddQ hade en intressat titel på ett av sina föredrag, Undvik ad-hoc i agila projekt. Innehållet fokuserades dock bara på modelbaserad testning och inte en gång rörde han vid frågan vad han menade med ad-hoc och varför ad-hoc tester skulle undvikas. Inte heller gav han något tips eller erfarenhetsbeskrivning som rörde titeln. Kändes mer som namnet på föredraget var själva tipset, hur man skulle fullfölja det verkade ovidkommande. Ställde en fråga om huruvida det finns testning som inte är modellbaserad, det får nog bli en ny post om den frågan.

Ett bättre alternativ var paneldebatten där fem figurer, föredragshållare, tillsammans på scen diskuterade agile. Diskussionen hettade till några gånger och det verkade vara en bra blandning av inriktningar. Mest imponerad blev jag av dansken John Fodeh som kom med klara och välformulerade inlägg. Formatet behöver slipas på men det är definitivt något jag vill se mer av.

Det är ändå så, som många påpekat, att det är i pauserna saker händer. Jag pratade med en del gamla kändisar men träffade många nya människor med intressanta åsikter och bakgrunder.