Kontakt os

I dagens tempofyldte softwareudviklingsmiljø det er sædvanligt at høre ordene Test-Driven Development (TDD). Diskussion om dens fordele såvel som ulemper er meget almindelige i softwareudviklingssamfundet.
Nogle siger, at TDD er en „urealistisk ineffektiv moralkampagne for selvafsky og skam“, og andre, at det „bare er et værktøj til at hjælpe os med at designe hurtigere ved hjælp af refactoring“ [2].
Dårlige programmører har alle svarene. Gode testere har alle spørgsmålene.“
— Gil Zilberfeld
Men testdrevet udvikling er ikke et nyt barn i byen.
Den tidligste kendte reference stammer fra 1957 i D.D. McCrackens „Digital Computer Programming: The First General Introduction in Book Form, Stressing Actual Work with Computers“. Selvom TDD ikke blev bredt vedtaget i de få år, der fulgte, IBM kørte et projekt for NASA i 1960'erne, hvor udviklere „skrev tidlige enhedstest til mikrotrin.
I løbet af en varm sommeraften i 1989 udviklede Kent Beck sig den første kendte TDD-ramme - SUNit - og prøvede det på Smalltalk. TDD blev derefter født eller, mere præcist, genopdaget. Kort efter begyndte Agile- og TDD-bevægelser at tilskynde programmører til at skrive automatiserede enhedstest og dermed tilføje test til udviklingsdisciplinen.
Først, som med mange nye ting, syntes det bare at „tilføje tid til dagjobbet“. De fleste af os forstod ikke helt fordelene ved at følge sådan praksis, da vi var skeptiske og kritiske over for TDD, da det blev betragtet som ganske unødvendig tid og kræfter.
Men inden vi går videre, lad os gå tilbage og overveje: Hvad er testdrevet udvikling?
I en nøddeskal TDD er handlingen med at skrive en automatiseret test, før du skriver en funktion.
Lad os som et eksempel sige, at Bob har brug for at udvikle en ny funktion til sin fantastiske nye sociale netværksidé. Bob starter med at skrive en automatiseret test, og selvom funktionen ikke er implementeret korrekt, vil testen mislykkes (dvs. rødt lys). Så Bob skriver den mindste mængde kode for at få testen til at bestå (dvs. grønt lys).
Så snart han har fået grønt lys, rydder Bob op i koden og sikrer, at funktionen stadig implementeres korrekt ved at køre testene (dvs. han omfaktorerer koden). Uden duplikationer er koden og automatiserede tests lette for andre at vedligeholde.
Denne procedure er også kendt som „rød/grøn/refactor mantra“, hvor rød betyder mislykkede prøver og grøn betyder beståede prøver. Robert Cecil Martin, en af lederne af den agile metodologibevægelse (og kendt for mange som onkel Bob), nævnte i „Clean Code“, at skrivning af tests før skrivning af produktionskode kun er toppen af isbjerget.
„Den eneste måde at nå fristen på - den eneste måde at gå hurtigt på - er at holde koden så ren som muligt til enhver tid.“
— Onkel Bob, Ren kode
For at fremhæve de reelle fordele ved TDD, laver vi en øvelse.
Lad os forestille os, at vi vil starte en ny softwareapplikation uden testdrevet udvikling. Vi implementerer en app, så brugerne kan administrere deres blog.
Lad os starte med at implementere vores første funktion: Tillad brugere at registrere sig for at oprette deres blog. Når koden er færdig, skal vi manuelt teste den for at se, om alt fungerer problemfrit.
Når vi er tilfredse med den første funktion, kan vi begynde at kode funktion nummer to: Tillad brugere at tilføje blogindlæg. Og når denne kode er færdig, tester vi den anden funktion manuelt for at se, om den fungerer korrekt. Når vi er glade, kan vi gå videre til den næste funktion, ikke?
Men... hvordan ved vi, at den nye kode ikke brød brugerregistreringsprocessen (første funktion)?
Vi kan teste den første funktion manuelt og se, om den stadig fungerer. Betyder det, at hver gang vi tilføjer en ny funktion, skal vi manuelt udføre N+1 tests?
Svaret er ja.
Resultatet er, at det er så utroligt dyrt at manuelt teste alle funktioner, når en ny udgivelse laves, at projekter uden TDD er meget tilbøjelige til regressioner. I softwareudviklingstermer sker der en regression, når en funktion, der fungerede i en tidligere udgivelse, ser ud til at være brudt i en senere udgivelse.
Konklusionen er, at projekter, hvor TDD anvendes, normalt har færre fejl end projekter uden automatiserede tests. Men automatiserede tests er ikke gratis.
På den anden side kan udvikling af en funktion med automatiserede tests koste 20% til 50% mere end uden test. Men efterhånden som softwarens kompleksitet vokser, bliver det stadig sværere at teste hver eneste funktion manuelt.
Efter implementeringen af et par funktioner betaler det sig allerede at investere tid i at skrive automatiserede tests.
I softwareudviklingssamfundet er det nu bredt accepteret, at projekter med automatiserede tests er mindre buggy end projekter uden automatiserede tests.
Det er også almindeligt accepteret, at omkostningerne ved at skrive en test betaler sig ved at forhindre fejl i at ramme produktionsmiljøet. Færre bugs betyder et bedre produkt. Og det oversættes normalt til lykkeligere brugere. For ikke at nævne gladere udviklere, der kan bruge deres tid på at lave et bedre produkt, i stedet for konstant at rette fejl.
Men hvor meget test er nok? Skal vi skrive automatiserede tests for hver enkelt funktion?
Svaret er: det afhænger.
I TDD er der ingen formel testplan, hvilket gør det til en uformel proces. Derfor er procentdelen af kode, der skal testes, en enorm debat.
„'Hvordan tester man? ' er et spørgsmål, der ikke kan besvares generelt. „Hvornår skal man teste?“ har dog et generelt svar: så tidligt og så ofte som muligt.“
— Bjørne Strøstrup, Programmeringssproget C++
Vi observerede, at det at bringe testdækningen til over 80% ikke giver større fordele. Vi havde så få fejl, der opstod, da vi anvendte 80% -reglen, at det at skrive endnu flere tests havde meget, meget marginale fordele.
For at sætte det i den virkelige verden, lad os bare tage et eksempel.
For nylig på et projekt for en omfattende platform blev vi på grund af et vist pres på deadlines for et par sprints tvunget til at reducere den automatiserede testdækning til 60% af koden.
Da nye funktioner blev frigivet med lavere dækning, begyndte vi at få flere regressioner. Efter at have gennemført to sprints med 60% kodedækning besluttede vi at bruge en hel sprint bare til at rette fejl og sætte testdækningen tilbage på sporet.
Havde vi ikke haft et fald i dækningen, ville vi kun blive forsinket med en halv sprint i stedet for en fuld sprint. Så det er en hel uge, vi kunne have sparet bare ved at øge vores testdækning i første omgang.
Forestil dig, hvordan nogen har det, når tiden bruges på at feje op efter dig selv og ikke bygge større og bedre ting.
Vores tommelfingerregel er altid at anvende automatiserede tests til de mest komplekse funktioner. Vi udvikler kun automatiserede tests for enkle funktioner, hvis dækningen uden disse er under 80%. Det betyder, at vi bruger mindre tid på at rette fejl, og færre problemer rejses af slutbrugerne.
Så for at opsummere, at Imaginær sky Vi elsker TDD og 80% kodedækning er vores magiske nummer.
Jo mere kompleks funktionen er, jo højere er den på vores testprioritetsliste.
Vi har et team af eksperter inden for softwareudvikling på Imaginær sky. Hvis du tror, du kunne bruge lidt hjælp til dit digitale projekt, så send os en linje her!

Fandt du denne artikel nyttig? Du kan måske også lide disse!

CEO @ Imaginary Cloud og medforfatter af bogen Product Design Process. Jeg nyder mad, vin og Krav Maga (ikke nødvendigvis i denne rækkefølge).
People who read this post, also found these interesting: