Kurt Nørmark
Institut for Datalogi, Aalborg Universitet
Sammendrag Forrige lektion Næste lektion Stikord Referencer Indhold | Når vi programmerer laver vi fejl. I denne lektion ser vi på hvordan vi håndterer sådanne fejl, og hvordan vi finder fejl via systematisk test. |
Fejl |
Forskellige slags fejl Slide Indhold Stikord Referencer |
|
|
Program: Programmet der beregner største fælles divisor med en funktion - OK. |
|
Program: Programmet med en logisk, algoritmisk fejl. |
|
Program: Programmet med en syntaksfejl. |
|
Program: Programmet med en køretidsfejl - måske afledt af en logisk fejl. |
|
Program: Programmet med en uendelig løkke - måske afledt af en logisk fejl. |
|
Hvornår finder vi fejl? Slide Indhold Stikord Referencer |
|
|
Hvordan finder vi fejl? Slide Indhold Stikord Referencer |
|
|
|
Hvordan finder vi årsagen til fejl? Slide Indhold Stikord Referencer |
|
|
Hvordan håndterer vi fejl? Slide Indhold Stikord Referencer |
|
|
|
Korrekthed - assertions Slide Indhold Stikord Referencer |
|
|
Program: En forkert implementation af my_sqrt. |
|
Program: Program output. |
|
Program: En brugbar - men primitiv - implementation af my_sqrt implementeret via rodsøgningsfunktionen. |
|
Program: En udgave af findRootBetween med præbetingelse og postbetingelse. |
|
Validering af brugerinput Slide Indhold Stikord Referencer |
|
Program: Læsning af double og input med input validering. |
|
Program: Læsning af double og input med input validering - i do-while input validerings løkke. |
|
Program: Læsning af double og input med input validering - rekursivt funktionskald. |
|
Opgave 7.2. Input validering med rekursiv funktion | Se på følgende variant af programmet vist på den tilknyttede slide. Hvad er problemet? #include <stdio.h> #include <stdlib.h> void clear_standard_input_line(void); void get_double_int_input(void); int main(void) { get_double_int_input(); return 0; } void get_double_int_input(void) { double x = 0.0; int i = 0, input_result; // Prompting for input of a double and an int: printf("Enter a double and an integer:\n"); input_result = scanf("%lf %d", &x, &i); if (input_result != 2){ clear_standard_input_line(); printf("Problems. Try again\n"); get_double_int_input(); } // Proceed - input OK - input_result == 2; printf("x = %f, i = %d\n", x, i); } void clear_standard_input_line(void){ int ch; while ((ch = getchar()) != '\n' && ch != EOF); } |
Funktioner der returnerer fejl-værdier Slide Indhold Stikord Referencer |
|
|
|
Fejlnumre og fejlmeddelelser i errno.h Slide Indhold Stikord Referencer |
|
Program: Et eksempel på brug af errno fra errno.h. |
|
Program: Output fra programmet. |
|
Program: Et mislykket eksempel på brug af errno - i forbindelse med division. |
|
Program: Godt alternativ: Forhindring af fejl. |
|
Program: Output fra programmet. |
|
Test af Funktioner |
Sporadisk afprøvning Slide Indhold Stikord Referencer |
|
|
Program: Eksempel på sporadisk afprøvning af daysInMonth og isLeapYear. |
|
Systematisk test Slide Indhold Stikord Referencer |
|
|
|
Black box test Slide Indhold Stikord Referencer |
|
|
Program: Diskussion af black box test af funktionen isLeapYear - ud fra funktionelle krav. |
|
Program: Selve funktionen isLeapYear - fokus på de funktionelle krav snarere end funktionens implementation. |
|
Program: Diskussion af black box test af funktionen daysInMonth - ud fra funktionelle krav. |
|
Program: Selve funktionen daysInMonth - fokus på de funktionelle krav snarere end funktionens implementation. |
|
Opgave 7.3. Test af programmet der beregner timer, minutter og sekunder | Vi har i rigt mål beskæftiget os med et program, der beregner timer, minutter og sekunder af et antal sekunder. Senest har vi i Opgave 6.2 programmeret en funktion hours_minutes_seconds, som er et godt udgangspunkt for denne opgave. Lav nu en systematisk test (black box unit testing) af følgende ønskede input og outputs til funktionen hours_minutes_seconds:
Du kan enten programmere dine tests med assert, eller med brug af CUTest. Hvis du bruger CuTest er detaljerne fra denne slide et godt udgangspunkt (kopier gerne fra slides programmerne). Bemærk lige at vi i denne opgave ikke tester output formatet (som gjort i opgave 3.4) - kun beregningerne af normaliserede timer, minutter og sekunder. |
White box test Slide Indhold Stikord Referencer |
|
Top-down test af funktioner Slide Indhold Stikord Referencer |
|
|
|
Figur. Illustration of function under test i relation til stubbe og driver. |
Systematisk test af C programmer Slide Indhold Stikord Referencer |
|
Program: Funktionen daysInMonth og tilhørende tests - isLeapYear er en stub. |
|
Program: Test driver for tests af funktionen daysInMonth. |
|
Program: Oversættelse og kørsel af programmet. |
|
Program: Oversættelse og kørsel af programmet - med forventing om 30 dage i januar. |
|
Program: Funktionen daysInMonth, isLeapYear og alle tilhørende tests. |
|
Program: Test driver for tests af funktionenerne daysInMonth og isLeapYear. |
|
Program: Oversættelse og kørsel af programmet. |
|
|
Opgave 7.4. Test af rod beregning i andengradspolynomium | Test funktionen solveQuadraticEquation fra en tidligere lektion, som er den funktion der sender rødderne tilbage gennem output parametre. Tag gerne udgangspunkt i løsningen på opgave 5.1, og lav top-down test af de fire funktioner solveQuadraticEquation, discriminant, root1 og root2. Med andre ord skal du altså teste den variant af programet som har fire funktioner (solveQuadraticEquation, discriminant-funktionen, og de to rod-funktioner), og hvor solveQuadraticEquation sender resultaterne tilbage gennem fire pointere. Overvej behovet for stubbe når du laver testcases for disse funktioner. Du skal gennemføre en systematisk (black box unit) test, som udvælger et mindre antal testcases, der har størst mulighed for at finde fejl. Programmer hver test case som en lille funktion. Du kan enten gennemføre testarbejdet med asssert eller med brug af CUTest. Følg mønstret for tests af daysInMonth og isLeapYear på den tilhørende slide. |
Systematisk test af C programmer med CUTest Slide Indhold Stikord Referencer |
|
Program: Funktionen daysInMonth og tilhørende tests. |
|
Program: Testdriver for tests af funktionen daysInMonth. |
|
Program: Kompilering og kørsel. |
|
Program: Kompilering og kørsel - med forventing om 30 dage i januar. |
|
Program: Funktionen isLeapYear og tilhørende tests - tilføjet til tests af daysInMonth. |
|
Program: Testdriver for tests af daysInMonth og isLeapYar. |
|
Program: Kompilering og kørsel. |
|
Program: Testdriver (uændret) og en alsidig variant af main som både rummer normal kørsel og testkørsel. |
|
Program: Kompilering og kørsel - normal og test. |
|
Opgave 7.5. Kom godt i gang med CUTest | Formålet med denne opgave at hjælpe dig i gang med brug af unit testing frameworket CUTest for C programmer. Der findes også en video som hjælper dig i gang med CuTest. Naviger til CUTest siden og download CUTest. I 2020 har den seneste version af CUTest nummer 1.5. Det du downloader er en ganske lille pakket fil (en zip-fil) med nogle få C programmer. Udtræk filerne fra den pakkede fil, og læs derefter README file. Denne udgør brugervejledningen til CUTest. Når du skal bruge CUTest er det lettest at kopiere filerne CUTest.C og CUTest.h til det katalog, hvor du har det C program, som du ønsker at teste. I README filen kan du læse, hvordan du oversætter og kører et testprogram, som er lavet med brug af CUTest. Prøv det gerne selv af på de programmer med tests, der er vist på den tilhørende slide (eller på et af dine egne programmer som du ønsker at teste). |
Refleksioner omkring CUTest Slide Indhold Stikord Referencer |
|
|
|
Dokumentation af Funktioner |
Dokumentation af Funktioner Slide Indhold Stikord Referencer |
|
|
Eksempler på dokumentation af funktioner og Doxygen Slide Indhold Stikord Referencer |
|
Program: Hele rodsøgningsprogrammet - underdokumenteret. |
|
Program: Dokumentation af program og funktioner i rødsøgingsprogrammet. |
|
Program: Hele rodsøgningsprogrammet - overdokumenteret. |
|
Program: Hele rodsøgningsprogrammet - main er sektions-dokumenteret. |
|
Program: Dokumentation af funktionerne i rodsøgningsprogrammet - beregnet for Doxygen. |
|
|
Opgave 7.6. Kom godt i gang med Doxygen | Formålet med denne opgave er at sætte dig i gang med at bruge Doxygen til dokumentation af C programmer. Der findes også en video, som supplerer denne opgave. Først skal du downloade Doxygen og installere programmet. Hvis du ønsker diagrammer skal du også downloade Graphviz pakken, og installere denne. Skriv nu et C program med dokumentationskommentarer, ligesom vist på rodsøgningsprogrammet. Start derefter Doxywizard, som giver dig mulighed for at sætte din dokumentation op. Der er en række forhold, som du skal være opmærksom på:
Doxygen er et meget rigt værktøj. Leg gerne med de mange muligheder for at tune dokumentationen til dine behov. |
Debugging af C programmer |
Debugging af C programmer Slide Indhold Stikord Referencer |
|
|
|
Opgave 7.7. Debugging af findRootBetween | Denne opgave går ud på at debugge - at bruge gdb - på programmet der søger efter en rod i en kontinuert funktion. Se gerne først videoen om gdb, og følg også gerne dele af den tutorial som er knyttet til kurset. Sæt et breakpoint når funktionen findRootBetween kaldes. Følg værdierne af de lokale variable l og u i takt med at while løkken udføres. Dette kræves at der sættes endnu et breakpoint. Kør programmet igen, og break ligesom tidligere i findRootBetween. Sæt en watch på variable u, og følg med i hvordan u ændrer sig i løkken. Leg gerne med andre aspekter af GDB med udgangspunkt i dette program. Det vil naturligvis også være fint at anvende gdb på andre af de programmer, du har skrevet i kurset. |
Flere opgaver Slide Indhold Stikord Referencer |
Opgave 7.8. Brug af assert i 'uger, dage, timer, minutter og sekunder' opgaven | I det velkendte program fra opgaven, der omregner et sekundtal til normaliserede uger, dage, timer, minutter og sekunder, er det attraktivt at sikre sig at de beregnede antal dage, timer, minutter og sekunder er inden for de forventede grænser (altså at de er normaliserede). Eksempelvis skal antallet af dage være mellem 0 og 6, og antallet af timer være mellem 0 og 23. Tilføj et antal anvendelser af assert, som sikrer at de beregnede antal uger, dage, timer, minutter og sekunder er normaliserede. Tilføj også et assert, der sikrer at det beregnede tidsdele 'kan regnes tilbage til' det oprindelige program input (det indlæste antal sekunder). Hvis dit program er korrekt, hører du intet fra assert. Prøv derfor evt. at introducere et par bevidste fejl i dine beregninger, så du kan se hvordan assert reagerer på dette. |
Samlede referencer Indhold Stikord |
|
Kapitel 7: Fejl, Debugging, Test og Dokumentation
Kursets hjemmeside Forfatteren's hjemmeside Om frembringelsen af disse sider Forrige lektion (top) Næste lektion (top) Forrige lektion (bund) Næste lektion (bund)
Genereret: 9. maj 2022, 13:59:22