Innhold
Det er laget en pdf-versjon av dette dokumentet som er egnet for utskrift på papir.
Testing er kvalitetssikring. Vi tester for å finne feil. En vellykket test finner feil i programkoden, designet, kravspesifikasjonen, behovsanalysen eller dokumentasjonen for det aktuelle systemet. Testing er bra for nattesøvnen til både systemutviklere og brukere. Testing fører til at feil finnes på et tidligere stadium av festen og det gir en besparelse.
Vi bruker fire testfaser, som vanligvis gjennomføres i denne
rekkefølgen (men gjerne i flere iterasjoner):
Alle disse testene utføres når systemet lages første gang og ved enhver senere ny utgave av systemet. Muligheten for å ta snarveier her behandles nedenfor under regresjonstest.
Testene i de to første fasen kalles glass-boks-tester, fordi testene gjerne forutsetter innsikt i systemets indre oppbygning. Metoder og verktøy for disse to testfasene er ofte ganske like, og det er ikke uvanlig at de flettes mer eller mindre sammen.
Testene i de to siste fasen kalles svart-boks-tester, fordi testene ikke
skal forutsette innsikt i systemets indre oppbygning. Metoder og verktøy
for disse to fasene er ofte ganske like. I prosjekter med sterk
brukermedvirkning er det derfor ikke uvanlig at de flettes mer eller mindre
sammen.
Usability testing (brukbarhetstesting) anbefales brukt av SAUS for
nesten alle systemer vi lager, men beskrives ikke i dette dokumentet. Usability
testing er et verktøy for å finne ut hvor lett systemet er å
forstå og bruke (og hva som kan forbedres), ved å observere
sluttbrukere i mest mulig realistiske brukssituasjoner. Usability testing er
svært nyttig når det brukes tidlig som et designverktøy, og
når det brukes for å finne ut hva som bør forbedres i
eksisterende systemer. Mens testfasene i dette dokumentet tester systemet i
forhold til ulike krav, tester usability testing designet mot "virkeligheten"
(i form av reelle brukere). Usability testing kalles ofte "brukertesting", men
dette bør unngås fordi ordet også brukes om "testing der
(super-)brukere deltar".
Med "uavhengig testing" menes testing utført av andre personer
enn de som har utviklet det systemet som testes. Dette er aktuelt i alle de
fire testfasene, brukes særlig i systemtest og er nesten ufravikelig i
akseptansetest. Uavhengig testing kan utføres av brukere eller av andre
systemutviklere enn de som har laget systemet.
For store deler av den systemutviklingen SAUS gjør er det vanlig at man ikke gjør noe uavhengig testing utenom den testingen som brukerne er med på eller selv utfører. For små datasystemer er det ganske vanlig at de som har utviklet systemet selv utfører mye av testingen. Det samme gjelder dersom det er få krav til systemets pålitelighet
SAUS legger stor vekt på tester der brukerne deltar (dette kalles også "brukertesting", men ordet bør unngås fordi det også brukes om usability testing). Systemeier (brukerne) har hovedansvaret for akseptansetest, som har til hensikt å gi systemeiers (brukernes) formelle aksept på at systemet (eller deler av dette) er klar til bruk. Det er systemeiers ansvar å påse at kunden får det de har betalt for. Derfor anbefaler vi at det gjennomføres akseptansetester.
Både enhetstest, integrasjonstest og systemtest krever den type kompetanse som systemutviklere har. Men i mange prosjekter er det aktuelt at brukere er med også i disse testfasene, særlig i systemtest. Tilsvarende er det normalt slik at systemeier (brukerne) vanskelig kan lage og gjennomføre akseptansetest uten medvirkning fra systemutviklere. I prosjekter med et nært samarbeid mellom brukere og systemutviklere endres ikke ansvarsfordelingen som er nevnt ovenfor, selv om begge parter er med på de ulike testfasene.
Utkastet til systemeieravtale er litt ekstremt ved å legge hele ansvaret for dokumentasjon og gjennomføring av systemtest på systemeier. Utkastet vil bli revidert.
De fire testfasene henger sammen med dokumentene som er beskrevet i dokumentasjonsguiden på følgende måten:

Enhetstesting er testing av den enkelte modul, typisk en klasse/kildekodefil. Testene har nær sammenheng med kildekoden, og er i praksis basert på denne (glass-boks-test). Enhetstest behøver ikke ta hensyn til helheten i systemet.
Enhetstesten bør ha som mål å teste all kode, selv om man kan argumentere for unntak for feilhåndteringskode for feilsituasjoner som "ikke kan skje" og som ikke kan fremprovoseres av testdata. Enhetstest kjøres på nytt hver gang modulen endres for å unngå regresjon.
Generelt er det ønskelig at mest mulig av enhetstestingen automatiseres (gjelder i enda større grad ved bruk av XP, eXtreme Programming). For automatisert testing gjelder:
Noen i SAUS bruker "junit" som rammeverk for atomatiserte tester, www.junit.org har en tutorial i junit for java, og www.xprogramming.com har under "downloads" linker til testrammeverk for mange andre programmeringsspråk, inkludert PL/SQL og Python. Se forøvrig presentasjonen fra første del av testseminaret SAUS: som pdf.
Integrasjonstest er neste nivå over enhetstest. Integrasjonstesten skal ikke dekke all kode, og heller ikke all funksjonalitet. Fokus er på det som ikke er med i enhetstestene. Det vil si at fokus er på at de enhetstestede modulene fungerer sammen som de skal.
Integrasjonstesten er en glass-boks-test som tar utgangspunkt i både koden og designet. Integrasjonstest kan noen ganger ses på som en samling enhetstester for større byggeklosser (for klasser som bruker de enhetstestede klassene). Integrasjonstesten utformes i hovedsak fra et teknisk perspektiv (dvs. ikke et brukerperspektiv).
Omfanget av integrasjonstest bør være vesentlig mindre enn systemtest. Integrasjonstesten må rekjøres hver gang integrasjonsklassene endres, eller noe de bygger på. Mye av testingen kan med fordel automatiseres. Dette er sterkt ønskelig ved bruk av XP, hvor man skal integrasjonsteste meget ofte (typisk hver dag).
Integrasjonstesten kan godt inneholde noe ad hoc testing i tillegg, for å ta noen av feilene man ikke har tenkt på å teste. Ad hoc testing betyr i denne sammenheng å klikke seg rundt i brukergrensesnittet på tvers av enhetene som systemet er bygget opp av. Ad hoc testing bør tas med når man har integrert seg opp til et nivå med et brukergrensesnitt.
Det kan være hensiktsmessig å droppe integrasjonstesten som formell testfase i mindre prosjekter, eller i prosjekter der integrerende moduler har enhetstester slik at disse i praksis virker som integrasjonstester.
Systemtesten er den viktigste sikringen for det vi i SAUS leverer fra oss er godt nok:
Systemtesten fokuserer på systemet som helhet, ikke de enkelte modulene. Systemtesten tester ikke alt som er testet i tidligere testfaser. Det er ikke et mål å teste all kode. Men systemtesten bør være grundig nok til å avdekke mange av feilene som ville kunne oppstå under normal bruk av systemet, selv om mange slike feil burde vært oppdaget under enhetstest.
Systemtesten skal være basert på kravspesifikasjonen, og skal være slik at den kunne vært laget uten kjennskap til koden (black-box-test). Hvis det ikke finnes en formell kravspesifikasjon, er det viktig at man tar noen skritt tilbake og prøver å se systemet fra et systemeier perspektiv når man skal planlegge systemtesten. Systemtesten blir i praksis en tolkning fra kravspesifikasjonen til hvordan systemet skal fungere praksis.
Ideelt sett bør i hvert fall deler av arbeidet utføres av andre enn de utviklerne som har laget systemet. Dette er viktigst for testplanlegging, men også ønskelig for deler av gjennomføringen av testene. Sannsynligheten blir da større for at man oppdager eventuelle misforståelser som skyldes tolkningen av kravspesifikasjonen.
Sekvensen av tester bør følge naturlige måter å bruke systemet som helhet, uavhengig av hvilke moduler som man kommer borti (f.eks. en ordre registreres, som så prosesseres av andre deler av systemet som naturlig i en ordres livsløp). Systemtesten bør inneholde komponenter som dekker behovene for driftstest (inkl. rutiner og dokumentasjon), stresstest, sikkerhetstest osv. Systemtesten bør også teste realistiske "eksterne" feilkilder (maskin dør, nett ned, LDAP nede, disk full).
En systemtest kan (og bør i en del tilfeller) være omfattende. Da er det naturlig å dele testene (kalles f.eks. testbetingelser) inn i grupper (som f.eks. kalles testcase), som så deles inn i større grupper (som f.eks. kalles testsykluser). Det blir ofte avhengigheter mellom tester gjennom testdata som gjør at f.eks. alle testene i et testcase må tas i sekvens, eller at mange av testcasene i en testsyklus må tas før en annen testsyklus.
Systemtesten bør inneholde tester som bruker testdata som er generert ved normal bruk av systemet (f.eks. for e-pay: bruke ordrer som er registrert gjennom e-pay, ikke bare ordrer laget av "testordre innleggingskode"). Samtidig bør systemtesten kunne restartes fra gitte punkt. Dette kan løses ved at man registrerer en del data gjennom systemet tidlig i systemtesten, og så lagrer dette (f.eks. database eksport) slik at det kan hentes inn igjen senere). Tilsvarende kan man gjøre for senere viktige punkter i systemtesten, som man vil kunne rekjøre fra (f.eks. etter bestemte testsykluser).
Akseptansetesten er konseptuelt sett samme type test som systemtesten (black-box-test). Den viktigste forskjellen er at andre er ansvarlige for denne testfasen enn for de andre testfasene (typisk systemeier isteden for USIT).
USIT vil normalt ikke være ansvarlig for akseptansetesten for systemer som er utviklet ved USIT. Men det er absolutt aktuelt for USIT å være ansvarlig for akseptansetest av et system vi kjøper inn fra et annet sted. Dersom systemeier har noenlunde tillit til organisasjonen som utvikler løsningen, blir akseptansetesten en slags punktkontroll av at den andre testingen (spesielt systemtest) er utført skikkelig.
Normalt har akseptansetesten et vesentlig mindre omfang enn systemtesten. Dette gjelder ikke nødvendigvis ved overtagelse av et system som er kjøpt til fastpris. Man forventer å finne vesentlig mindre feil enn i systemtesten fordi:
For systemtest og akseptansetest er testdekning et spørsmål om i hvilken grad testene faktisk verifiserer alle spesifiserte krav til systemet.
For enhetstest og integrasjonstest er testdekning et spørsmål om i hvilken grad all kode faktisk er blitt utført under testene, og i hvilken grad de ulike veiene gjennom koden er testet. I praksis er det alltid umulig å teste alle mulige veier gjennom koden. Så man må velge ut de viktigste, noen typiske/normale situasjoner og noen ekstreme situasjoner.
Regresjonstest betyr gjentagelse av en eller flere testfaser for å verifisere at feilrettinger eller endringer ikke har introdusert nye feil eller uønskede effekter, og at systemet fremdeles tilfredsstiller spesifiserte krav. Ved regresjonstest utføres en utvalgt del av de aktuelle testfasene, og hensikten er å spare tid i forhold til å utføre alle testene. Regresjonstest er aktuelt både i forbindelse med feilretting under nyutvikling og når man senere lager nye utgaver av systemet.
Regresjonstest kommer selvfølgelig i tillegg til de testene som må kjøres for å verifisere at feilrettingen eller endringen fungerer som spesifisert. I forbindelse med regresjonstest må man alltid ta stilling til hvilke deler av den totale samling av tester som i den gitte situasjonen bør kjøres på ny. Og det kan være ganske vrient. Problemet er at man ved regresjonstest ikke får full testdekning, med mindre man kjører alle tester hver gang.
Selv om en test avdekker feil skal alle testene i den aktuelle testfasen om mulig gjennomføres og testrapport skrives. Deretter rettes feilene og det kjøres regresjonstest på den aktuelle testfasen i henhold til den detaljerte testplanen.
SAUS har et minimumskrav til testdokumentasjon, og det er at det skal lages en overordnet testplan. Dokumentasjonsguiden gir noen eksempler på testdokumentasjon vi har utarbeidet.
Overordnet testplan behøver ikke være et separat dokument, men kan for eksempel være integrert i prosjektetplanen. Testplanen beskriver på et overordnet nivå hva som er viktigst å teste, om og hvordan enhetstest, integrasjonstest og systemtest skal gjennomføres, med ansvar, ressurser, milepæler, fremgangsmåte, testverktøy og lignende. Hvis USIT skal spille en aktiv rolle i en eventuell akseptansetest, bør dette også beskrives på et overordnet nivå. Se disposisjonfor overordnet testplan
Planen kan gi regler for klassifisering av feil funnet under test, for eksempel i tre nivåer: kritisk, ordinær, kosmetisk. Planen kan også gi regler for antall/art av feil for godkjenning og forkasting av det som testes. For eksempel: Modulen godkjennes ikke dersom testen avdekker kritiske feil eller mer enn 3 ordinære feil.
Detaljerte testplaner skal være separate dokumenter beregnet
på aktiv bruk under gjennomføring av tester, og utformet slik at
resultatet av hver enkelt test kan noteres der å da i dokumentet. Det er
ikke uvanlig at en testfase avdekker så mange feil at systemet må
oppdateres og testfasen gjentas. En detaljert testplan er derfor beregnet
på gjenbruk, vanligvis med noen oppdateringer for hver gang den
brukes.
Ved automatisert testing som del av enhetstest og integrasjonstest,
erstattes både testplan og testlogg av testkode (men evt. avvik der man
går videre uten at alle automatiserte tester passerer bør noteres
i en form for testlogg).
For hver av de fire testfasene lages en detaljert testplan som beskriver hver enkelt test som skal gjennomføres. Hver enkelt test beskrives ved å angi hva som skal testes, inndata, kommandoer/håndgrep og ikke minst forventet resultat av testen (fasit). Dette kan være utformet som skjema til loggføring mens testingen pågår, og derved danne grunnlag for utforming av testrapport vanligvis som et vedlegg til testrapporten. Se mal for detaljert testplan.
Detaljerte testplaner oppdateres og gjenbrukes hver gang systemet endres, i hele systemets levetid.
Hver gang en testfase er fullført utformes en rapport som oppsummerer resultatet av testingen, med testloggen som vedlegg. Rapporten skal primært beskrive og kategorisere de feil som er funnet. Testrapporter er beslutningsunderlag for prosjektleder og styringsgruppe i spørsmål om prosjektets videre gang, ut fra art og antall av de feil som er funnet.
Testrapport er bare aktuelt i store prosjekter. For små prosjekt holder det at testloggen brukes som testrapport.