
10 minute read
2.5 Feilsøking
DISKUTER
Synes du at disse testene dekker alt det er naturlig å bruke handlelisten til? Er det noe du burde ha lagt til? Er det for eksempel noen knapper som det ikke er klikket på?
EKSTRASTOFF
Det er lurt å skrive testene før koden
I dette delkapittelet har vi testet kode som vi allerede har skrevet. Det er imidlertid god praksis å skrive testene før vi skriver koden. Når vi skriver testene etter at koden ferdig, er det flere menneskelige faktorer som gjør at kvaliteten på testene blir dårligere, blant annet: • Vi har ikke lyst til å finne feil i noe vi allerede har lagt mye arbeid i. Derfor har vi lett for å forhaste oss, og vi tar ikke oppgaven med å tenke som en motstander på alvor. • Testingen virker som unødvendig ekstraarbeid: Vi eksperimenterte jo mens vi laget programmet, og det må da være godt nok. Andre oppgaver haster, og det er fristende å droppe testingen, slik at vi kan begynne på dem. • Vi er sliten og lei av oppgaven som vi har holdt på med en stund nå. Vi har ikke overskudd til å skrive like gode tester som vi hadde gjort dersom vi hadde skrevet dem før vi begynte på oppgaven. Hvis vi skriver testene, eller et utkast til dem, på forhånd, klarer vi sannsynligvis å komme på flere av forventningene en ny bruker møter nettsiden eller programmet med, og vi tar arbeidet mer alvorlig. Å skrive testene trenger ikke å ta mer enn noen få minutter. Det er ikke nødvendig å skrive ned alle stegene og få med alle kravene med en gang. Det er heller ikke sikkert at alle kravene til programmet er klare før vi har jobbet litt med det. Det viktigste er at vi gjør så mye vi kan, slik at vi kan forbedre testene etter hvert. Det er ingen som forventer at du som er elev alltid skal skrive tester på forhånd. Det er helt greit at du skriver tester etter at du har skrevet koden. Når du har fått mer erfaring, kan du prøve deg litt frem. Du kan for eksempel skrive en test før du legger til en ny knapp i et eksisterende program.
Feilsøking handler om å finne ut hvorfor et resultat ikke er som forventet. Med mindre du har rettet opp i handlelistekoden, feilet begge testene i forrige delkapittel. Når vi klikker på «Legg til vare» og pluss- og minusknappene, tilbakestilles navnet på varene vi har lagt til tidligere, men ikke antallet. Dette er en utilsiktet feil som oppsto da vi skrev koden, men som vi har beholdt, slik at vi kunne bruke den til å demonstrere feilsøking.
NOTER DET DU TROR ER FEIL, OG UNDERSØK DET
Det første du bør gjøre når du skal feilsøke, er å skrive ned alt du tror kan være opphav til feilen, i en tekstfil. Da unngår du å miste tråden underveis eller glemme gode ideer. Hvis du må be andre om hjelp, er det veldig nyttig for dem å vite hva du har sett på, og da kan du vise dem tekstfilen. Når du har funnet feilen og løst den, kan du ta vare på filen, slik at du kan lære av det du har gjort.
Da testene fra forrige kapittel feilet, noterte han som hadde skrevet koden, følgende:
• • Har jeg misforstått hvordan bind: virker? Fungerer bind: bare på attributter i HTML-elementer og ikke på egenskaper i
Svelte-komponenter? • Fungerer det bare på tall? (Jeg har jo klart å binde til antall, og det ser ut til å virke selv om vi legger til varer.) • Har jeg skrevet feil noe sted?
Når du har funnet feil, bør du notere deg hva feilen er, og hva du tror er årsaken til den. Hvis du ikke finner ut hva feilen skyldes med én gang, kan du • lese dokumentasjonen for språket eller verktøyet du bruker • logge kjørende kode med funksjonen console.log • bruke utviklerverktøyet i nettleseren
LESE DOKUMENTASJON OG HJELPERESSURSER PÅ NETTET
For å sjekke om vi har forstått det kodetekniske riktig, kan vi lese dokumentasjonen for programmeringsspråket eller kodeverktøyet vi jobber med. Dokumentasjonen er bruksanvisningen til språket eller verktøyetvi bruker. Den forklarer hva vi kan gjøre, og er ofte supplert med interaktive kodeeksempler og bilder av forventede resultater.
Hvis du har lastet ned et kodeverktøy fra en nettside, finner du ofte dokumentasjonen ved å se etter en lenke på siden med teksten «Getting started», «Documentation», «Docs», «API», «Readme» og lignende. Du kan også søke på nettet etter verktøyets navn etterfulgt av «documentation».
Ikke alle verktøy har en egen hjemmeside. Det finnes for eksempel ingen nettside der du laster ned HTML, CSS og JavaScript. Disse språkene er bygd inn i nettleseren. Det betyr at nettleseren kan lese koden og vise frem resultatet. Hvis du åpner «Hjelp»-menyen i nettleseren, får du bare hjelp til å bruke nettleseren, ikke til å lage dine egne nettsider. Det betyr at du må finne dokumentasjon for språkene andre steder.
Dokumentasjon for Svelte, Javascript, HTML og CSS
Du finner dokumentasjon om hvordan du lager Svelte-komponenter, på https://svelte.dev/docs. Hvis du bruker SvelteKit, som brukes for å sette sammen flere filer til større nettsider, finner du dokumentasjonen på
https://kit.svelte.dev/docs. www.w3schools.com er et begynnervennlig nettsted der du kan finne dokumentasjon for HTML, CSS og JavaScript. Mer viderekomne programmerere pleier som regel å bruke Mozilla Developer Network (MDN), som de finner på https://developer.mozilla.org/. Sidene til MDN er ofte mer oppdatert og innholdsrike, men bruker språk og eksempler som er mer teknisk avanserte enn sidene til W3Schools.
For å få svar på spørsmålet «Har jeg misforstått hvordan bind: virker?» og de to tilhørende spørsmålene gikk vi til Svelte-dokumentasjonen og søkte på teksten «bind:». Vi fikk nesten 70 treff, som vi skumleste på leit etter relevante opplysninger.
Følgende setning ga et ganske tydelig svar på det ene spørsmålet: «You can bind to component props using the same syntax as for elements.» Det betyr at vi kan skrive bind: både i HTML-elementer og Svelte-komponenter og forvente at det fungerer likt. Det var dessuten ingenting i dokumentasjonen som sa at vi bare kan binde til tall og ikke strenger. Med andre ord hadde vi forstått hvordan bind: fungerer.
FEILSØKING I KJØRENDE PROGRAMKODE
Vi kan se på hendelsesforløpet fra programmet starter til det uønskede resultatet oppstår, som en tidslinje som beveger seg mot høyre etter hvert som brukeren trykker på knapper og angir informasjon i grensesnittet og linjene i programmet kjører. Feilsøking handler om å finne ut akkurat hvor på tidslinjen programmet begynner å oppføre seg annerledes enn forventet.
Det enkleste – og kanskje mest brukte – verktøyet for å få oversikt over tidslinjen, er funksjonen console.log. Denne funksjonen henter inn data og viser dem i den såkalte konsollen, slik at vi kan se hva de underliggende verdiene er. Vi setter inn console.log før og etter en kodelinje for å undersøke hva verdien var før og etter at denne linjen ble kjørt. Det er også nyttig å bruke console.log til å forstå når og i hvilken rekkefølge koden kjøres. Hvis meldingene aldri dukker opp i konsollen når vi forventer dem, eller hvis de dukker opp i en uventet rekkefølge, har vi sannsynligvis skrevet noe feil.
Se konsollen på Svelte.dev/repl
På https://svelte.dev/repl kan du trykke på «Console» nederst til høyre for å se hva som har blitt skrevet til konsollen.
Nederst til høyre ser vi at strengen "Hei" har blitt lagret i konsollen.

ÅPNE UTVIKLERVERKTØYET PÅ EN HVILKEN SOM HELST NETTSIDE
De færreste nettsider har et sted i dokumentet der vi kan klikke for å se hva som er skrevet til konsollen. Derfor må vi åpne utviklerverktøyet (developer tool på engelsk) til nettleseren, som er et eget vindu der vi kan finne informasjon som er interessant for utviklere, men ikke for vanlige brukere.
Når du er inne i en spesifikk fane i nettleseren og vil åpne utviklerverktøyet for å se på innholdet i denne fanen, kan du bruke følgende tastesnarveier: • Windows og Linux: Ctrl + Shift + I • Mac: Command + Option + I
For å beskytte brukere mot ondsinnede angrep har Apple valgt å deaktivere utviklerverktøyet i Safari som standard. Hvis du bruker Safari, må du derfor slå på utviklerverktøyet ved å åpne innstillingene (trykk på Cmd + ,), gå til fanen «Avansert» og klikke på «Vis Utvikle-menyen i menylinjen».

Når du har åpnet utviklerverktøyet, klikker du på fanen «Console» (eller «Konsoll» i Safari), hvis den ikke allerede er åpen.
Nå skal vi se hvordan vi brukte console.log for å finne feilen i handlelisteprogrammet. Det første vi ville gjøre, var å forsikre oss om at navn faktisk ble endret inni Teller når koden kjører. Da endret vi funksjonen som lå i «Lagre»-knappen ved å legge inn to console.log-utsagn.

EKSEMPEL
Konsollen som angrepsflate
Folk med ondsinnede hensikter kan lure intetanende ofre til å lime skadelig kode inn i konsollen og kjøre den. Ofte dukker slik kode opp i kjedebrev med løfter om at koden for eksempel skal hjelpe mottakerne med å se hvem som er inne på profilen deres, eller med å få flere «likes». Slik ondsinnet kode klikker på knapper og sender forespørsler på brukerens vegne. Resultatet er som regel at angriperen får tilgang til offerets konto og sensitiv informasjon. Noen ganger sprer slik kode seg til offerets omgangskrets ved at den sender meldinger til offerets venner eller legger ut innlegg på offerets vegne med de samme oppfordringene og løftene. For å stoppe slike angrep viser noen populære nettsteder en advarsel når noen åpner konsollen på det aktuelle nettstedet. Du kan trygt bruke konsollen på nettsider du selv har skrevet.

Prøv å legge inn de tilsvarende endringene i koden på datamaskinen din, og gjennomfør testtilfelle #1 fra kapittel 2.4.
1 <button 2 on:click={() => { 3 console.log("Navn var", navn) 4 navn = endringsforslag 5 console.log("Navn endret til", navn) 6 endrerNavn = false 7 }}
8 > 9 Lagre 10 </button>
Når du har utført testen, ser konsollen slik ut:
Linjen oppfører seg med andre ord som forventet. Variabelen navn som inneholdt verdien "Ny vare", får den nye verdien etter at du har klikket på «Lagre». Her begynte vi å mistenke at det var noe galt i måten handleliste.svelte reagerte på endringer fra Teller på. Derfor la vi inn følgende linje i slutten av script-blokken i handleliste.svelte:

Prøv å legge til denne linjen i handleliste.svelte på datamaskinen din, og gjennomfør testtilfelle #1 fra 2.4 på side XXX igjen. Noter det du observerer.
$: console.table(varer)
console.table er en variant av console.log. Forskjellen er at console. table viser dataene vi gir den, som en tabell. Det er praktisk når vi jobber med arrayer. Fordi linjen starter med $:, kjører den når en av verdiene i varer endrer seg. Altså burde vi se en melding i konsollen hver gang vi endrer antall eller navn for en av varene.
Da vi utførte testen, så loggen slik ut etter at vi hadde lagt til kaffe og epler:
Hvis vi følger med på loggen mens vi utfører testen, er det lett å se når ting går galt. Når vi har gitt et nytt navn til det første objektet i arrayet, bør vi for eksempel se en melding i konsollen, men den dukker aldri opp. Når vi deretter legger til en ny vare i listen, dukker det opp en melding som viser at det første objektet i arrayet aldri fikk en ny verdi.
Hvor tror du det er sannsynlig at feilen ligger med utgangspunkt i det vi har gjort av logging og feilsøking til nå? Hva ville ha vært ditt neste steg i feilsøkingsprosessen hvis du ikke har noen mistanke?

DISKUTER
På dette tidspunktet bestemte vi oss for å lese gjennom all koden som hadde med sammenkobling av listen og Teller-komponenten å gjøre, og da så vi fort hva feilen var. Vi hadde glemt å sette inn bind: foran egenskapen navn i Teller-komponenten. Koden var altså:
1 <Teller 2 navn={vare.navn} 3 bind:verdi={vare.antall} 4 />
Vi oppdaterte koden slik:
1 <Teller 2 bind:navn={vare.navn} 3 bind:verdi={vare.antall} 4 />
Hvis vi retter denne feilen og kjører testene på nytt, blir resultatet som forventet både for testtilfelle #1 og #2.
FEILSØKING ER SJELDEN GØY, MEN FEILEN ER SOM REGEL ENKEL
Når feilsøking forklares i undervisningssammenheng, er det lett å få inntrykk av at det er en enkel og følelsesløs prosess: «Finn feilen, gjør sånn og slik, og vips så har du løst det.» I virkeligheten er feilsøking forbundet med en del frustrasjon. Selv de som har mange års erfaring som programmerere, blir frustrert når koden ikke virker som forventet.
Når vi oppdager årsaken til en feil, virker den ofte veldig åpenbar. Slike feil er både en lettelse og en skuffelse. Det tar kort tid å rette dem opp, men de burde jo ikke ha
