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:

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:

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:

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