Sådan tester du ny software effektivt, en komplet guide

Sådan tester du ny software effektivt, en komplet guide
Foto: Jakub Zerdzicki / Pexels

Hvorfor grundig softwaretest er uundværlig

Mange projekter ender med fejl i produktion, fordi testfasen er blevet nedprioriteret eller gennemført for hastigt. Det er en dyr fejl. Fejl der opdages efter lancering koster langt mere at rette end fejl der fanges tidligt, både i udviklertimer, brugerfrustration og i værste fald tabt tillid til produktet.

Effektiv softwaretest handler ikke om at køre et enkelt tjek og krydse fingre. Det handler om at have en struktureret tilgang, der dækker systemet fra mange vinkler. Denne guide gennemgår de centrale testtyper og viser, hvordan du bygger en testproces der rent faktisk virker.

Vil du forstå, hvad der ellers påvirker kvaliteten og omkostningerne ved et softwareprojekt, er det relevant at læse om hvordan man gennemfører et succesfuldt softwareudviklingsprojekt, mange af de principper hænger direkte sammen med testing.

De fire grundlæggende testtyper

Softwaretest er opdelt i lag. Hvert lag tester noget forskelligt, og tilsammen giver de et pålideligt billede af systemets tilstand.

Enhedstest

Enhedstest (unit tests) tester den mindste mulige enhed i koden, typisk en enkelt funktion eller metode, isoleret fra resten af systemet. Formålet er at verificere, at hvert enkelt stykke logik opfører sig som forventet under givne betingelser.

Disse tests skrives som regel af udviklerne selv, og de bør køre automatisk hver gang koden ændres. En høj dækning af enhedstest giver hurtig feedback og gør det nemmere at refaktorere kode uden at bryde noget.

Integrationstest

Når individuelle komponenter virker i isolation, er næste trin at teste, om de virker sammen. Integrationstest kontrollerer samspillet mellem moduler, tjenester og databaser. Her opdages fejl der opstår i grænseflader, for eksempel at to korrekte komponenter sender data til hinanden i et forkert format.

For systemer med en separat backend er integrationstest særligt vigtig. Du kan læse mere om, hvordan man bygger og optimerer backend-arkitektur i guiden om optimering af backend for ydeevne.

Systemtest og end-to-end-test

Systemtest tester hele applikationen som én samlet enhed. End-to-end-test (E2E) simulerer reelle brugerflows fra start til slut, for eksempel at oprette en bruger, logge ind, udføre en handling og logge ud igen. Disse tests er langsommere end enheds- og integrationstest, men de verificerer at systemet faktisk virker for brugeren i praksis.

Værktøjer som Playwright, Cypress og Selenium bruges hyppigt til at automatisere end-to-end-tests, særligt i webapplikationer.

Accepttest

Accepttest er det sidste lag inden lancering. Her bekræftes det, at softwaren opfylder de krav og forretningsregler der er aftalt med kunden eller stakeholders. Disse tests beskrives typisk i klarsprog frem for teknisk kode og kan involvere ikke-tekniske interessenter.

Manuel test versus automatiseret test

Mange tror fejlagtigt at automatiseret test kan erstatte manuel test fuldstændigt. Det kan den ikke. De to tilgange supplerer hinanden.

Automatiseret test er velegnet til repetitive tjek: regression (at sikre at gammel funktionalitet stadig virker), belastningstests og deterministische flows. Manuel test er uundværlig til brugeroplevelse, visuel kontrol og udforskende test, det vil sige test hvor man aktivt leder efter uventede fejl uden et foruddefineret script.

En god tommelfingerregel er at automatisere det der kører hyppigt og er stabilt, og bruge manuel indsats der, hvor menneskelig vurdering gør en forskel.

Udforskende test, undervurderet og effektiv

Udforskende test er en disciplin, der kræver erfaring og nysgerrighed. I stedet for at følge et testscript går testeren aktivt på jagt efter uventede problemer ved at tænke som en kritisk bruger eller en angriber.

Det er her man typisk finder de fejl, der falder uden for de kendte testscenarier, edge cases, race conditions og sikkerhedshuller. Sæt god tid af til udforskende test, særligt inden en større lancering.

Hands interact with smartphone for analyzing cryptocurrency trading on digital screens.
Foto: Jakub Zerdzicki / Pexels

Ydeevnetest og belastningstest

Selv om en applikation virker korrekt under normale forhold, er det ikke sikkert den holder, når mange brugere tilgår den samtidig. Ydeevnetest, herunder load testing og stress testing, afslører flaskehalse i systemet, inden de rammer rigtige brugere.

Typiske parametre der måles er svartid, gennemstrømning (requests per sekund) og fejlrate under belastning. Værktøjer som k6, JMeter og Locust bruges hyppigt til dette formål.

Hvis du udvikler en mobilapp, er det ligeledes relevant at vurdere appens effektivitet systematisk, herunder dens ydeevne under belastning og på forskellige enheder.

Sikkerhedstest, ikke et valgtilbud

Sikkerhedstest er obligatorisk i enhver seriøs udviklingsproces. Det dækker over at kontrollere for kendte sårbarheder som SQL-injektion, cross-site scripting (XSS), usikre sessionshåndteringer og forkerte adgangsstyringer.

Automatiserede sårbarhedsscannere kan afdække lavthængende frugter, men en reel penetrationstest, udført af erfarne sikkerhedsspecialister, er nødvendig for kritiske systemer. Sikkerhed bør ikke behandles som et punkt man tilføjer til sidst; det bør bygges ind i hele udviklingsprocessen fra starten.

Test i et CI/CD-pipeline

Moderne softwareudvikling integrerer tests i et automatiseret pipeline, typisk beskrevet som CI/CD (Continuous Integration / Continuous Deployment). Princippet er enkelt: hver gang koden ændres og skubbes til versionskontrollen, køres testsuiten automatisk.

Hvis en test fejler, stopper pipelinen, og koden deployes ikke. Det forhindrer at fejlbehæftet kode når produktion, og det tvinger teamet til at holde testsuiten grøn som en løbende prioritet frem for en engangsøvelse.

Platforme som GitHub Actions, GitLab CI og Bitbucket Pipelines gør det relativt enkelt at sætte dette op, selv for mindre teams.

Three professionals discussing financial charts and graphs during a business meeting.
Foto: https://kaboompics.com/ / Pexels

Testdækning, et nyttigt men ufuldstændigt mål

Kodedækning (code coverage) angiver, hvor stor en andel af koden der faktisk eksekveres under testene. Det er et nyttigt mål, men det er vigtigt at forstå dets begrænsninger: høj kodedækning garanterer ikke at systemet er fejlfrit. Det garanterer kun at koden er eksekveret, ikke at alle mulige udfald er testet korrekt.

Brug kodedækning som et pejlemærke og ikke som et mål i sig selv. Fokusér på kvaliteten af testene frem for at jagte et bestemt procenttal.

Praktiske råd til at opbygge en god testproces

Test tidligt og test ofte. Jo tidligere en fejl opdages, desto billigere er den at rette. Det er en af de mest veldokumenterede kendsgerninger inden for softwareudvikling.

Skriv tests som en del af udviklingsprocessen, ikke som en eftertanke. Mange teams bruger testdrevet udvikling (TDD), hvor man skriver testen inden man skriver selve koden. Det tvinger en til at tænke over kravene, inden man begynder at kode.

Sørg for at fejlede tests altid rettes hurtigt. Et team der tillader sig selv at ignorere fejlede tests, mister hurtigt tilliden til sin testsuite, og dermed dens værdi.

Dokumentér testscenarier og -resultater. Det gør det nemmere at onboarde nye teammedlemmer og giver et klart overblik ved fremtidige ændringer i systemet.

Kom godt i gang

Effektiv softwaretest kræver ikke nødvendigvis et stort budget eller et dedikeret QA-team fra dag ét. Det kræver en bevidst tilgang, de rette værktøjer og en kultur i teamet, hvor kvalitet er et fælles ansvar.

Uanset om du bygger en hjemmeside, en mobilapp eller et komplekst backendsystem, er en struktureret testproces det der adskiller software der fungerer fra software der skaber problemer. Du kan finde yderligere perspektiver på udviklingsprocessen hos Sahari, der arbejder med sikker softwareudvikling og kan give en uforpligtende snak om, hvad der passer til netop dit projekt.

Kontakt os