Gå til hovedinnhold

Hvordan skrive automatiserte akseptansetester

Når ny funksjonalitet er utviklet basert på akseptansekravene, må det vurderes hvilke av kravene som skal ha automatiserte tester.

Målgruppe​

  • Utviklere som skal implementere step definitions

Forutsetninger​

Hvordan playwright-bdd fungerer​

Vi bruker playwright-bdd for å koble Gherkin-krav til Playwright-tester. Verktøyet fungerer som en bro mellom de lesbare kravene og den faktiske testkoden.

Fra Gherkin til kjørbar test​

Flyten fra krav til kjørbar test består av flere steg:

  1. bddgen leser .feature-filer fra krav/-mappen
  2. Genererer Playwright-testfiler i .features-gen/
  3. Hvert steg i Gherkin matches mot en step definition
  4. Playwright kjører de genererte testene

Du trenger aldri å redigere filene i .features-gen/ - de genereres automatisk hver gang du kjører bddgen. Det du skriver er step definitions som kobler Gherkin-stegene til faktisk testkode.

Step definitions​

En step definition er en funksjon som utfører det et Gherkin-steg beskriver. Når Gherkin-filen sier Når jeg lagrer, må det finnes en step definition som vet hvordan "lagre" skal utføres i applikasjonen.

When('jeg lagrer', async ({ page }) => {
await page.getByRole('button', { name: 'Lagre' }).click();
});

Step definitions skrives i TypeScript og bruker Playwright for å interagere med applikasjonen. De plasseres i steps/-mappen, organisert etter domene.

Parametre i steps​

For å unngå å skrive mange nesten-like step definitions, kan du bruke parametre. playwright-bdd støtter flere parametertyper som {string} for tekst i anførselstegn, {int} for heltall, og {word} for enkeltord. Se playwright-bdd dokumentasjonen for komplett oversikt.

Gjenbrukbarhet​

En av de største fordelene med BDD er at step definitions kan gjenbrukes på tvers av scenarioer. Når du skriver Når jeg lagrer i ti forskjellige scenarioer, trenger du bare én step definition.

Finn eksisterende steps​

Før du skriver en ny step definition, sjekk alltid om det finnes en som kan gjenbrukes. Søk i tester/steps/-mappen etter relevante nøkkelord. Over tid bygger teamet opp et bibliotek av gjenbrukbare steps som gjør det raskere å automatisere nye krav.

Claude Code kan hjelpe

Hvis du gir Claude Code tilgang til fs-repoet, kan den raskt finne eksisterende steps som matcher det du trenger. Spør for eksempel "finnes det en step for å logge inn?" eller "hvilke steps har vi for opptak?".

Skriv gjenbrukbare steps​

Tenk på gjenbrukbarhet når du formulerer steg. En step som Når jeg lagrer kan brukes i mange kontekster, mens Når jeg lagrer opptaket kun fungerer i opptak-scenarioer. Generiske formuleringer gir mer fleksibilitet, men noen ganger er det riktig å være spesifikk for å gjøre scenarioet mer lesbart.

Implementere nye steps​

Når du må skrive en ny step definition, trenger du å forstå hvordan applikasjonen fungerer. Du må vite hvilke UI-elementer som finnes og hvordan brukeren interagerer med dem.

Claude Code kan hjelpe

Hvis du gir Claude Code tilgang til frontend-repoene (fs-admin, min-kompetanse) og GraphQL-skjemaet, kan den hjelpe deg med å finne riktige selektorer for UI-elementer eller forstå hvilke felter og mutasjoner som er tilgjengelige i API-et.

Bruk Playwright Codegen med Claude​

Playwright Codegen lar deg ta opp interaksjoner i nettleseren og generere kode. Kombinert med Claude får du en effektiv arbeidsflyt for å lage step definitions.

For FS-Admin (saksbehandler):

npx playwright codegen --lang no-Nb $FS_ADMIN_URL

For MinKompetanse (student/søker):

npx playwright codegen --lang no-Nb $MIN_KOMPETANSE_URL

Flagget --lang no-Nb sikrer at Codegen bruker norsk locale, slik at knapper og elementer får riktige navn.

Arbeidsflyt:

  1. Kjør Codegen-kommandoen i terminalen
  2. Logg inn med Feide testbruker
  3. Gjennomfør hele scenarioet du skal automatisere
  4. Kopier all generert kode
  5. Lim koden inn i Claude sammen med scenarioet fra feature-filen
  6. Claude strukturerer koden til gjenbrukbare step definitions

Eksempel på dialog med Claude:

> Jeg har kjørt gjennom dette scenarioet i Codegen:
>
> Scenario: Opprette nytt opptak
> Gitt at jeg er logget inn som saksbehandler
> Når jeg oppretter et nytt opptak med navn "Test"
> Så skal opptaket vises i listen
>
> Her er koden Codegen genererte:
> [lim inn kode]
>
> Kan du lage step definitions for dette?

Claude: Jeg ser at du har disse interaksjonene. La meg først sjekke
hvilke steps som allerede finnes...
[Claude finner eksisterende steps og lager kun de som mangler]

Claude vil identifisere hvilke steps som allerede finnes, og lage nye step definitions kun for de som mangler.

userContext-fixture​

Vi bruker alltid userContext-fixture i stedet for page. Dette gir oss konsistent håndtering av roller og innlogging på tvers av alle tester.

Viktig: Alle scenarioer må starte med innlogging:

Gitt at jeg er logget inn som administrator

Dette er påkrevd fordi userContext bruker lazy initialization - den oppretter ikke en nettleserkontekst før switchTo() kalles. Tilgjengelige roller er:

Tilgjengelige brukerroller for testing
RolleApplikasjonBeskrivelse
administratorFS-AdminSaksbehandler
personMinKompetanseStudent/søker
personsok-administratorFS-AdminSaksbehandler med tilgang til personopplysninger

I step definitions bruker du userContext.currentPage for å få tilgang til Playwright sin page:

When('jeg navigerer til opptak', async ({ userContext }) => {
await userContext.currentPage.getByRole('link', { name: 'Opptak' }).click()
})

Organiser steps etter domene​

Step definitions organiseres i filer etter domene. Generelle steps som "lagre", "navigere" og "logge inn" legges i common.steps.ts, mens domenespesifikke steps legges i egne filer som opptak.steps.ts eller student.steps.ts. Dette gjør det enklere å finne eksisterende steps og forstå hva som er tilgjengelig.

Testdata og isolasjon​

Hver test skal opprette og bruke kun sin egen testdata. Dette sikrer at tester kan kjøres uavhengig av hverandre og i vilkårlig rekkefølge.

Setup og teardown​

Når Gherkin-filen har en Bakgrunn: som sier "det finnes et opptak som heter X", må step definition opprette dette opptaket før scenarioet kjører. Etter at scenarioet er ferdig, skal testdataen ryddes opp.

Dette betyr at:

  • Tester er ikke avhengige av data som "tilfeldigvis" finnes i testmiljøet
  • Tester påvirker ikke hverandre
  • Tester kan kjøres parallelt
  • Feilsøking blir enklere fordi hver test starter fra kjent tilstand

Bruk unike, gjenkjennelige navn på testdata slik at det er lett å identifisere hvilken test som opprettet dem. Dette gjør det enklere å feilsøke hvis noe går galt.

Repoer og tilganger​

For å skrive gode step definitions trenger du forståelse for applikasjonene du tester. Dette innebærer tilgang til relevante repoer:

Relevante repoer for testutvikling
RepoInnholdBrukes til
fsKrav og testerFeature-filer og step definitions
fs-adminAdmin-frontendForstå UI-elementer
min-kompetanseStudent-frontendForstå UI-elementer

Kjøre testene lokalt​

Fra tester/-mappen i fs-repoet har du flere kommandoer tilgjengelig:

Kommandoer for lokal testkjøring
KommandoBeskrivelse
npm testKjører bddgen og alle tester
npm run test:headedKjører tester med synlig nettleser (nyttig for debugging)
npm run test:smokeKjører kun tester tagget med @smoke
npm run test:nightlyKjører kun tester tagget med @nightly
npm run test:nightly:headedKjører nightly-tester med synlig nettleser
npm run bddgenGenererer testfiler fra features uten å kjøre testene

Når kjører testene automatisk?​

Testene kjøres automatisk i to situasjoner:

  • Smoke-tester (@smoke) kjøres hver gang en merge til fs-admin lager et nytt image. Dette verifiserer at kritisk funksjonalitet fungerer etter deploy.
  • Nightly-tester (@nightly) kjøres hver natt mot functionaltest-miljøet. Dette fanger opp regresjoner på tvers av alle repoer.

Automatiske kjøringer gir oss et sikkerhetsnett, men erstatter ikke lokal testing under utvikling.

Ressurser​