Test af Programmer

Fra HTX-Arduino
Skift til: navigering, søgning
Video med forklaring til kapitlet


Det at teste et program kan lyde ret simpelt - virker det efter hensigten, så er testen OK, virker det ikke, så er der en fejl der skal findes. Det passer også helt fint, hvis det er så simpelt som programmet Blink (se Blink Eksempel), men hvis programmet håndterer flere forskellige ting, så er problemstillingen at teste grundigt straks mere kompliceret.

Når man tester sit program, så vil man tit finde nogen fejl i program-opførslen, så skal man finde de fejl. Det kan også tit være en udfordring.

Testopstilling

Hvis man laver et program der kan fungere som en termostat[1], så kan man for eksempel lave det koblet op i en opstilling som vist i figur 1.

Opstilling med simpel termostat
Figur 1 Opstilling med simpel termostat.

Som det kan ses i figur 1, så er der en temperatursensor LM35, der kan måle temperaturen via en analog indgang og en 47 ohm modstand der fungerer som varmelegeme. I princippet kan opstillingen fint fungere som termostat og holde en temperatur på fx 30 grader - man kan bare ikke se det. Man kan måske mærke at modstanden er varm, men er det fordi den er tændt hele tiden, eller fungerer reguleringen som den skal?

For kunne teste om termostaten fungerer, så en man nødt til at have en idé om, om den faktisk regulerer eller hvad temperaturen egentlig er. Hvis man vil måle temperaturen, så kan det være en god idé at lukke modstand og temperatursensor inde i et lille rum, og så have et termometer med inde i rummet, og så observere hvad temperaturen bliver.

En anden mulighed er at se om der faktisk tændes og slukkes for varmelegemet, ved at koble en lysdiode parallelt over - det er selvfølgelig ikke en garanti for at temperaturen er korrekt, men det kan indikere om reguleringen arbejder som den skal.

En tredje mulighed er at bruge Serial Monitor[2], hvor man kan skrive ud hvilken temperatur der måles, og om der varmes.

Vil man gå videre med termostaten, så kan det være en ide at lave variabelt setpunkt, og en visning i et display. På den måde får man en mere brugbar termostat. Samtidigt bliver det lettere at teste den.

Testparametre

Første betingelse for at kunne teste struktureret er at man har opstillet en kravspecifikation[3], så man har en ide om hvad programmet skal opfylde af krav. Ud fra kravene kan man opstille en række test-parametre, så man sikrer sig at man får testet de situationer igennem som programmet skal kunne håndtere.

En typisk fejl når man tester er, at man kun tester på den måde man har tænkt programmet til at fungere. Et program skal ikke reagere uhensigtsmæssigt, hvis det bliver udsat for situationer man ikke har planlagt/tænkt over. I værste fald kan et program låse eller fungere meget uhensigtsmæssigt, hvis det bliver fejlbetjent, det kan være meget uheldigt. Hvis for eksempel termostaten varmer konstant mens man indtaster et nyt setpunkt, så vil det fungere lidt uheldigt, men ikke katastrofalt, det kan dog være ret uheldigt hvis brugeren ikke afslutter indtastning, og programmet så ikke selv kommer ud af den tilstand. Værre er det hvis man konstruerer et program til en hjerte-lunge-maskine. Der kan det være fatalt med den slags uhensigtsmæssigheder...

Som det kan ses af eksemplerne, så er det vigtigt at tænke sin test grundigt igennem, så man også får testet for ting man ikke umiddelbart har planlagt. Samtidigt skal man heller ikke gå i ekstremerne - hvis man for eksempel kan indtaste et tal, så behøves man ikke nødvendigvis at indtaste med alle mulige tal, men man skal stadig prøve at fremprovokere fejl - hvis det for eksempel også er muligt at indtaste bogstaver, så skal man teste at det ikke kan føre til fejl i programmets opførsel, og man skal også prøve om man kan indtaste for mange/for få/ingen cifre - om der sker noget ved negative tal osv.

Hvis et program kan befinde sig i flere forskellige tilstande, så skal man teste igennem at tingene fungerer i alle tilstande, det kunne føre til tabel 1 over testparametre:

regulering manuel visning setpunkt indtast setpunkt valg af mode
normalt tal
negativt tal
et ciffer
20 cifre
bogstaver
ingen tal

Tabel 1 Tabel over kombinationer at testparametre.


Som det kan ses i tabel 1, så er der 30 situationer der skal testes igennem. Det kan godt være at nogle af felterne kan vurderes som overflødige, hvis programmet slet ikke reagerer på indtastninger under visning af setpunkt, så kan man måske nøjes med at teste at det faktisk er tilfældet.

Hvis programmet samtidigt udfører en anden opgave, som fx har 10 forskellige ting der skal testes, så er det lige pludselig 300 tilstande man skal teste igennem - det kan blive ret omfattende.

Test under udvikling

Det er naturligt at man udvikler sit program og tester løbende. Dette betegnes som Stepwise Improvement[4].

Her skal man passe på at man ikke bare tester det man lige har udviklet, og så derefter regner med at det stadig er i orden, uanset hvad man ellers laver af videreudvikling på programmet. Der kan gå mange ting galt, men specielt tidsforhold og sammenblanding af variabler er ting der ofte går galt under udvikling af programmer.

Det betyder at man er nødt til at forholde sig til hvilke testparametre det er relevant at teste, og i det mindste huske at få testet alt igennem i en slut-test.

Målinger

Specielt når man arbejder med Arduino og tilsluttet elektronik, så kommer man ikke ud over at man skal forholde sig til forskellige måder at måle på Arduinoen, for at kunne finde ud af hvordan programmet indeni forløber, og om det faktisk reagerer som forventet.

En simpel måde at måle på kan være ved at sætte en lysdiode (husk formodstand) til et ben for at se om det har et højt eller et lavt niveau, eller man kan bruge voltmeter-funktionen i et multimeter[5] for at se hvad der er på de forskellige ben. Begge metoder kan kun håndtere signaler der er så langsomme at det menneskelige øje kan følge med (kan registrere blinken til mellem 10 og 50 Hz).

Hvis signalerne bliver hurtigere, så skal man have fat i andet måleudstyr som et oscilloskop[6] eller en logik-analysator(“Logik-analysator,” 2015) for at kunne registrere hvad det er programmet laver.

En anden måde at finde ud af hvad der sker i programmet er ved at skrive noget ud i Serial Monitor[7], så man kan registrere programforløbet og evt. hvad der sker i forskellige variabler. Ved denne form for “måling” skal man være opmærksom på at man faktisk kan ændre tidsforholdene i programforløbet ret meget, da det tager tid at skrive noget ud til Serial Monitor. Se Serial Monitor for nærmere beskrivelse af hvordan man bruger Serial Monitor.

Fejlfinding

Når man skal fejlfinde i sine programmer, så er det vigtigt at man gør sig klart hvilket niveau man fejlfinder på.

For det første skal man kunne oversætte sit program. Det kræver at det er skrevet med den korrekte syntaks, ellers vil Arduinoen IDE ikke oversætte det til maskinkode, og når det er lykkedes, så skal der være hul igennem til Arduinoen som beskrevet i Software og Udviklingsmiljø for man kan komme videre med sin fejlfinding.

For det andet skal programmet udføre de algoritmer man har fastlagt under sin dokumentation af koden, hvis det for eksempel er eksemplet med termostaten, så kan algoritmen være at der skal tændes for varmen hvis temperaturen er under setpunktet og der skal slukkes for varmen hvis temperaturen er over setpunktet. Hvis den gør det modsatte, så vil programmet fungere uhensigtsmæssigt, og man skal have fundet ud af hvor man har lavet en fejl.

Hvis programmet udfører de algoritmer som det skal, men koden stadig ikke fungerer, så kan det være fordi der ligger fejl i det elektriske kredsløb - det kan være at programmet tænder for varmelegemet, men at det faktisk ikke varmer - det kan skyldes at man ikke har sat benet op til at være output, eller det kan være en elektrisk fejl i kredsløbet omkring varmelegemet.

En fjerde fejltype er at man kan have sat de forkerte algoritmer op i sin dokumentation, så programmet overholder algoritmerne, men at de ikke løser den kravspecifikation[8] man har sat op. Så må man tilbage til tegnebrættet og finde nogle algoritmer der kan leve op til kravene.

Erfaringsmæssigt er det vigtigt at skelne i mellem hvilken af de 4 typer fejl man arbejder med, når man skal fejlfinde, da det ellers kan blive uoverskueligt at lede efter fejlene. Det er også god praksis at teste dele af koden for sig, ved at man anvender Stepwise Improvement[9] i sin udvikling, i stedet for at man laver en “big bang” test, hvor man kan have flere forskellige fejl at arbejde med på samme tid, så man har svært ved at skille dem fra hinanden.

Tager man eksemplet med termostaten kan man starte med at måle temperaturen, og registrere om man faktisk kan registrere en temperaturændring. Så kan man koble varmelegemet på, og teste om det faktisk kan varme ved at man kan tænde og slukke det manuelt eller i nogle lange intervaller. Så kan man koble regulering på med et fast programmeret setpunkt, og så til slut lave styringen med et variabelt setpunkt, så man kan indstille den ønskede temperatur. På den måde kan man minimere hvor mange forskellige fejl man arbejder med ad gangen, og dermed lette sin fejlfinding.

Referencer