onsdag den 2. juni 2010

Når manuel unit test begynder at drive dig til vanvid

Har du nogensinde siddet og sammenlignet xml dokumenter, ledt efter forskelle i små og store bogstaver, manglende attributter og værdier som ligger uden for scope?

Hvis du har så kan du må måske blive inspireret her.

Situationen var, at vi på dette projekt havde identificeret integrationspunkterne som de mest kritiske og vi havde reelt set kun mig som tester. Men ok – sådan er det vidst mange steder. Jeg havde i flere dage siddet og kigget mig fuldstændig blind i xml dokumenter, attributter og manglende elementer og værdier som ikke var lige inden for scope – og det var ved at drive mig til vanvid.

Det var ikke helt inden for scope at vi havde talt automatisering af disse test, men jeg måtte bevise overfor projektledelsen at det kunne betale sig. Så en dag hvor projektlederen havde ryggen til mig en hel dag, så tog jeg fat og fik automatiseret omkring 30 ud af de 200 af de unit test jeg sad og skulle køre manuelt. Med NUnit var det relativ nemt at kode de unit tests, for jeg var så dybt inde i hvordan testcasene var bygget op, at der kun var slaveprogrammering tilbage.

Projektledelsen var godt klar over at unit testen var vigtig og at den tog i omegnen af 4-5 dage at gennemføre manuelt, med stor risiko for at testeren var helt skeløjet efterfølgende.

Nu tog det under 2 min at køre de 30 unit test igennem......

Projektledelsen var super begejstret, så efter endnu 5 dage, så havde jeg automatiseret de resterende 170 unit tests. Nu tog testen ca. 10 min at gennemføre. Men det er også en horibel forskel fra 4-5 dage og til 10 min.

Så var jeg nu arbejdsløs? Næ, nu kunne jeg begynde mig at koncentrere mig at designe endnu dybere test cases og begynde at test de andre dele af systemet.

Gevinsten var rigtig stor for udvikleren som sad med integrationerne, for det som han oplevede var, at han kunne få lukket sine opgaver hurtigt. Udvikleren og jeg sad i tæt dialog, udvikleren kodede og jeg trykkede på knappen for at køre unit testen, udvikleren havde nu et svar 2 min efter på det interface og kunne rette ind straks. Unit testen kunne fortælle udvikleren helt præcis hvor der var fejl og selvfølgelig var der tiltider også fejl i testen, men det vigtigste var at der blev skabt en rigtig god dialog mellem udvikleren og projektet og integrationspunkterne blev nu konstant overvåget af unit testen.

Fordi unit testen var så nem at køre, og fordi udvikleren fik svar tilbage straks, så blev der ikke brugt tid på at rapportere defects. Kun i de tilfælde hvor udvikleren var på andre opgave, var vi nød til at dokumentere en fejl grundigt.

Det er svært at få dækket alle scenarier med test cases, så der var også situationer var systemet fejlede men unit testen lyste grønt. Så nu gik øvelsen ud på, at få unit testen til at lyse rødt – altså kode en unit test, som rapporterede en fejl netop i den nye situation. Herefter var der kun hårdt arbejde tilbage for udvikleren og et tryk på unit test knappen i ny og næ.

Alt i alt en ret stor succes for testen. Det endte med at ca. 350 unit test var automatiseret og de blev kørt på omkring 10-12 min. Jeg kan på det varmeste anbefale, at man koder sig ud af sådanne situationer, så man ikke brænder testerne helt af.

tirsdag den 1. juni 2010

Kickstartet med 120 regressionstest på 4 uger

Testautomatisering kan også være en succes, det behøver ikke gå så galt som jeg skrev om i mit sidste indlæg.

Jeg blev stillet overfor en udfordring, som jeg var meget tæt på at sige nej til, men mit konkurrence instinkt drev mig til, at kaste mig ud idet.

Kunden havde stillet mig over for det opgave, at de ville have automatiseret 120 regressionstest, som skulle køre på deres daglige byg hver nat. De havde i forevejen automatiseret nogle af regressionstestene, så de ville bare have, at jeg skulle automatisere resten inden for de næste 3 uger.

Men .... med en del erfaring i baggagen, så udspurtge jeg udviklingschefen og testmanageren grundigt omkring, hvordan deres miljøer var sat op, hvordan deres testprocesser var skruet sammen, om testcasene havde den rigtige detaljeringsgrad og om de havde mandskab til at tage over, når nu vi havde nået målet.

Det så ud til at de havde de rette forudsætninger, men jeg måtte stille spørgsmålstegn til det eksisterende automatisering, for det det lød vidst som om, at der var noget kunne være en stor risiko.

Hvad jeg erfarede var, at den eksisterende kode, var lavet på næsten samme erfaringsgrundlag, som jeg havde på et af mine første projekter. Ganske rigtigt, koden var stort set udbrugelig og udviklingschefen måtte slå sig godt i tøjret, da jeg måtte meddele ham, at han skulle acceptere, at de sidste 6 måneders indsats skulle skrottes.

Med mit efterhånden mangeårige basisframework i hånden, så kunne jeg inden for den første uge danne største delen af frameworket til applikationen. De første regressionstest kom også i mål, og vi kunne efterhånden se, at der nu kun var hårdt arbejde tilbage.

Næste step var at få implementeret testene i det daglige byg og rapporteringen.

Resten af regressionstestene kom på plads i fjerde uge og nu var der kun uddannelse af deres udvikler og en tester tilbage. De to personer tilsammen skulle tage over og fortsætte automatiseringen. Udvikleren kunne nu se, hvordan han med frameworket, var i stand til at kode robuste testscripts. Testeren blev uddannet i at scripte en smule, så han kunne bygge testcasene op og udvikleren kunne varetage det hårde bagvedliggende programmeringsarbejde.

Jeg har desværre ikke hørt, hvordan det siden hen er gået dem, men jeg forstiller mig at kan bidrage med nogle kommentarer til dette indlæg, med lidt viden om hvordan gik efterfølgende.

Når testautomatisering går galt

Dette er en ærlig beretning om, hvor galt det kan gå, når man starter forkert.

Men først en tak til Unions for at sponsere mine dyrtkøbte erfaringer. Vi troede alle sammen på det, men det blev desværre ikke den succes som vi alle gerne ville have haft det til at være.

Denne historie er mine refleksioner over et mine af de første testautomatiserings projekter.

Med en business case i hånden, som godtgjorde for en besparelse på nogle mio. kr. pr år, plus et kvalitetsløft af vores webapplikation og en intro fra en ”ekspert” i brugen af QTP, så begav vi os ud i projektet at automatisere regressionstesten.

Eksperten gennemførte et lille pilotprojekt, som viste os hvordan vi forholdvis nemt kunne optage og afspille de testcases som testerne havde designet. Det så lækkert ud og var ret meget en wow oplevelse, at se webapplikationen blive betjent automatisk. Så hvorfor skulle det dog ikke blive en succes.

Jeg fik en kort introduktion til hvordan vi kunne optage og afspille og hvad QTP ellers havde af smarte ting. Så med min udviklerbaggrund og en del erfaring med automatisering af unit test, så kunne det da ikke gå galt.

Vi mente at vi havde alle de rigtige forudsætninger:
  • En testproces som kørte på skinner
  • Super dygtige testere 
  • Engagerede udviklere og testere
  • Flere tusind testcases
  • Scrum som udviklingsproces
  • Automatisk deployment af miljøer og byggemand bob til at styre dem
  • Automatisk udrulning af databaser og patchlevels
  • Et Quality Center som var perfekt styret og sat op
  • Et Quality Center team til vedligeholdelse af tilpasningerne
  • Alle krav i QC og styring af kravdækning
  • En skarp testmanager
  • En skarp udviklingschef
  • En udvikler (undertegnede) til at varetage testautomatiseringen
Webapplikationen var bygget op på et ganske godt grundlag, med et eget udviklet framework i jsp og javabeans ( udviklerne kan nok bidrage med lidt mere her ? ).

Målet var at automatisere regressionstesten. I sig selv et rigtig godt startsted for testautomatisering.

Det første vi gjorde var, at begynde at lære QTP at kende. QTP kan rigtig mange ting, men der er ikke rigtig noget, som fortæller om, hvordan man skal starte. Man kan selvfølgelig starte med Mercury’s flight booking applikation – den viser faktisk vejen ret langt hen af vejen, men den fortæller ikke principperne i hvordan man skal starte. Så det handlede mest om at forsøge at optage nogle skevenser, dernæst tilrette dem, så de blev datauafhængige og så sætte dem sammen til en testcase.

Det så også rigtig godt ud til at starte med og vi kom også rimelig langt, men der blev lidt for meget spaghettikode og vi fik aldrig tænkt over, hvilke lag testautomatiseringen skulle indholde og hvorfor. Det bevirkede at det blev rigtig svært at vedligeholde testen og fejlfinde i den. QTP er så heller ikke verdens stærke debugging værktøj og der følte jeg mig sat noget tilbage, da jeg var vant til at udvikle i visual studio.

Da det ikke rigtig lykkedes med QTP, tog vi kontakt til Examinator og startede et pilot projekt op omkring automatisering med TestBench og TestDrive. Produktet så meget lovende ud og vi håbede til det sidste at det ville lykkedes. Men for mit eget vedkommende, så tiltalte deres produkt mig ikke rigtig, da jeg synes at jeg mistede kontrollen over hvordan automatiseringen skulle køre – der var næsten ingen scripting muligheder og alt var point and click – du var virkelig lagt i hænderne på værktøjet og det muligheder oig begrænsninger.

Til sidst mistede alle troen på at det ville blive en succes og jeg måtte videre til nye opgaver.

Hvad har jeg så lært med tiden?
  • at man skal bygge frameworket til testautomatisering op lige efter bogen.
  • at frameworket er delt op et basis framework til og et framework dedikeret til den applikation, som skal automatiseres.
  • at det kræver et meget test samarbejde mellem en udvikler og en tester
  • at det kræver tålmodighed fra ledelsen
  • at man er godt hjulpet, hvis man bliver kickstartet rigtigt og får bygget det rigtige framework fra starten.
  • at man ikke skal tro at automatisering af capture/replay
  • at man skal kende sit værkstøj og dets begrænsninger
  • at testautomatiseringen ikke ligger i testafdelingen, men mest af alt skal placeres i udviklingsafdelingen.
  • at det kræver rigtig god kommunikation og kemi mellem udviklere og testere
Jeg har ikke det eksakte tal på, hvor meget at det kostede, men det var ikke billigt at få den lærdom. Vi brugte 6 måneder på at få det til at lykkes, men uden noget rigtig held.

Jeg håber at mine gode kollegaer fra den tid kan bidrage med deres syn på dette indlæg, jeg tror i hvert fald at der mere vi kan lære.

fredag den 28. maj 2010

Automatiseret GUI test med NUnit

Jeg er stor fortaler for at bruge QTP til automatisering af GUI. Det er et rigtig godt værktøj, hvis man forstår at bruge det rigtigt. Det er kun én ting, som begrænser brugen af QTP - det er prisen.

Prisen for en licens ligger i hvert fald i det leje, hvor en lille virksomhed som min, ikke har råd til at benytte sig af de fantastiske ting man kan med QTP.

Nu er jeg så heldig at jeg kan scripte QTP og har endda bygget et framework, som gør det rigtig nemt at automatisere især webapplikationer, men hvad nytter det, når jeg ikke kan bruge det til mine egne applikationer.

Så hvad gør jeg, når jeg har både BSBoksen og Rojabo.com med funktionalitet til en masse brugere, men ikke har råd til at have testere gående eller råd til at købe en QTP licens? Jeg bygger selvfølgelig mit eget GUI test framework, bygget op over NUnit.

Jeg bruger NUnit til al unit test på backend systemerne til rojabo.com og NUnit og ASPUnit til bsboksen.dk. Men jeg manglede at gå et niveau længere op i V-modellen for at få dækket behovet for regressions test på brugergrænsefladen.

Frameworket er meget inspireret af hvordan QTP fungerer, så mange af metodekaldene er de samme. Men da det er bygget i VB.NET, så har jeg pludselig meget nemmere adgang til at bygge et framework, som er bygget op efter alle kunstens regler for en lag opdelt applikation.

Indtil jeg for taget mig sammen til at skrive et indlæg omkring, hvordan frameworket er bygget op, så kan du more dig med en lille videooptagelse af hvordan mit framework løber igennem 33 regressionstests med i alt 100 assertions på under 4 min.


Spar tid på både udvikling og test

Vil du gerne spare mange udviklingstimer på tilbageløb og fejlrettelser, og ville dine testere godt undvære at afvikle regressionstesten manuelt gang på gang?

Vil dine udviklere gerne have hurtigt svar tilbage fra testen, så fejlrettelser bliver gjort mens udvikleren har koden frisk i hukommelsen og opgaverne derved bliver rigtig lukket?

Testautomatisering betyder: automatisk afvikling af test og automatisk rapportering af fejl.

Dvs. der er ingen personer til at starte testen og  ingen personer til at afvikle testen – kun en person til at læse og forstå rapporten om, hvordan testen af applikationen gik.

Hvis ja - så er løsningen er testautomatisering – men pas på !!!

Der er mange som igangsætter testautomatisering, men havner i en af de mange faldgrupper der findes. Det som jeg oftest har set er, at man sætter en ung udvikler eller en tester uden udviklerbaggrund til at begynde automastisering af testen. I starten ser det rigtig godt ud og alle klapper i hænderne over det magiske i, at se sin applikation blive betjent af en maskine – se helt uden hænder :-)

Desværre viser det sig, at den kode som er blevet genereret af værktøjet ikke er holdbart i det lange løb. Efter noget tid, og fordi applikationen man tester udvikler sig, begynder man ikke at kunne afvikle sine scripts så smertefrit som i starten og man begynder at bruge rigtig meget tid på vedligeholdelse. Til sidst opgiver man helt at køre testen automatisk, da scriptet simpelthen fejler så mange gange, at det kræver en mand på sidelinien til at køre det. Resultat er, at testautomatiseringen stoppes, og bliver lagt på hylden med store skuffelser og tabte investeringer.

Desværre er mange automatiseringsværktøjer så som QTP er tidligere blevet solgt på, at det stort set bare drejer som om capture/replay og en smule scripting. Men automatisering af test er absolut ikke nogen banal opgave. Automatisering er programmering/udvikling på linie med gængs applikationsudvikling. Man skal starte rigtig, bygge koden op efter alle kunstens regler med lag opdelt applikations layout og at testene skal være er designet rigtigt.

Alt i alt så kræver automatisering en stor værktøjskasse, med masser af erfaring inden for applikationsdesign, platforme, sprog, databasedesign, scripting og testdesign.

Udover alle de hardcore tekniske kompetancer det kræves, så er gode kommunikationsevner og pædagogisk indsigt værd at foretrække, da det kræver sit, at få testere og udviklere til at samarbejde og få begge parter til at forstå hinandens berettigelse.

Men når det hele går op i en højere enhed, så er genvinsten stor.
  • Kvaliteten af softwaren bliver højere
  • Udviklingstiden bliver mindre
  • Refactoring af applikationen bliver overskueligt
  • Udviklerne føler sig i høj grad hjulpet 
  • Testerne føler sig forstået. 
  • Kunderne bliver gladere
  • Leverance tidspunkterne bliver nemmere at overholde
  • Og ikke mindst – Du får ro i maven når du releaser

Organisationsmæssigt så har man ofte kompetancen inhouse til at fortsætte automatisering og vedligeholdelsen, for den besides ofte af en senior udvikler og en tester i samarbejde.