Præsentation er lastning. Vent venligst

Præsentation er lastning. Vent venligst

Forelæsning Uge 10 – Torsdag

Lignende præsentationer


Præsentationer af emnet: "Forelæsning Uge 10 – Torsdag"— Præsentationens transcript:

1 Forelæsning Uge 10 – Torsdag
Opremsningstyper Enumerated types Forskellige teknikker til test og debugging Når man tester undersøger man, om opførslen (semantikken) er den ønskede Når man debugger (afluser), forsøger man at finde ud af, hvorfor opførslen ikke er, som man ønskede og forventede StringBuilder klassen Opbygning af lange tekststrenge Projektopgave om computerspil I kursets sidste fem uger skal I, sammen med en makker, programmere et computerspil Der er fem delafleveringer og de indgår tilsammen med ca. 30% i den endelige karakter for kurset

2 ● Opremsningstyper (enumerated types)
Type, hvor brugeren eksplicit bestemmer de mulige værdier Nedenstående type har 8 mulige værdier Bemærk at værdierne ikke er tekststrenge Man bruger værdierne ved f.eks. at skrive Weekday.THURSDAY public enum Weekday { // A value for each weekday, // plus one for unrecognised commands. MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY, SUNDAY, UNKNOWN } 8 værdier Alternativet kunne man repræsentere ugedagene ved hjælp af heltal [1,7] eller ved hjælp af tekststrenge Heltal ville være sværere at forstå, og hvad betyder det, hvis man har en illegal værdi som 17 eller -3 Tekststrenge kan let indeholde stavefejl (f.eks. "Tusday") Det kan de selvfølgelig også, når vi bruger en enumereret type Men dem vil compileren fange

3 Mere komplekse enumerations
Opremsningstype typer kan også indeholde feltvariabler og metoder Man bruger stadig værdierne ved f.eks. at skrive Weekday.THURSDAY public enum Weekday { MONDAY("Monday"), TUESDAY("Tuesday"), WEDNESDAY("Wednesday"), THURSDAY("Thursday"), FRIDAY("Friday"), SATURDAY("Saturday"), SUNDAY("Sunday"), UNKNOWN("?"); private String weekday; Weekday(String weekday) { this.weekday = weekday; } public String toString() { return weekday; 8 værdier (de har nu en tekststreng som parameter) Feltvariabel af type String Konstruktør Opdaterer feltvariablen Konstruktører for enum typer er altid private Man kan ikke tilføje nye værdier toString metode returnerer værdien af feltvariable weekday String repræsentation af ugedagen

4 Eksempel på brug public static void test() {
Weekday day2 = Weekday.TUESDAY; Weekday day6 = Weekday.SATURDAY; Weekday dayX = Weekday.UNKNOWN; print(day2); print(day6); print(dayX); } Eksempel på brug Erklæring af tre lokale variabler af typen Weekday Udskrift via hjælperutine private static void print(Weekday day) { String dayString; switch( day ) { case MONDAY: case TUESDAY: case WEDNESDAY: case THURSDAY: case FRIDAY: dayString = " is a workday"; break; case SATURDAY: case SUNDAY: dayString = " is a day off"; default: dayString = " is an invalid day"; System.out.println( day + dayString ); } Lokal String variabel Switch sætning (med variabel fra opremsningstype) Værdi fra Weekday typen (toString metoden i Weekday) Tekststreng fra switch sætning

5 ● Unit tests Test af en afgrænset programenhed, f. eks.
Klasse Metode Unit tests kan f.eks. foretages ved hjælp af BlueJ's inspektorer Viser værdien af feltvariabler (og klassevariabler)

6 Positive og negative tests
Et positivt test undersøger om programenheden opfører sig som forventet Bliver en persons navn opdateret til den tekststreng, som vi angiver i kaldet af setName metoden? Et negativt test undersøger om programenheden opfører sig fornuftigt i fejlsituationer Hvad sker der, hvis vi forsøger at sætte navnet til den tomme streng eller alderen til noget negativt eller meget stort? Begge typer tests er vigtige Man er ofte tilbøjelig til at glemme (eller nedprioritere) de negative tests Lad være med det

7 Regressions tests (automatiske tests)
Regressions tests (regression ≈ tilbageslag / forværring) Når man ændrer i en klasse, bør man efterfølgende tjekke, at alting stadig fungerer korrekt (dvs. opfylder passende positive og negative tests) Har man ved et uheld fået ødelagt noget, som tidligere fungerede? Det er tidskrævende og kedeligt at lave regressions tests Regression tests bliver derfor ofte udeladt Det kan koste enorme mængder af tid, når man senere finder en mærkelig fejl og ikke aner, hvordan og hvornår den er opstået Løsningen er at lavetests, der let (og automatisk) kan gentages Man definerer en mængde af positive og negative tests Hvilke operationer skal udføres? Hvad skal resultatet være? Derefter er det op til test systemet (i vores tilfælde BlueJ) at gennemføre testene og tjekke om de giver de forventede resultater Det kan gøres på få millisekunder – uden programmørens medvirken Med automatiske tests er det langt mere overkommeligt at lave systematiske regression tests

8 Automatiske tests i BlueJ
BlueJ indeholder et test system ved navn JUnit Nemt at bruge Anvendes i mange andre programmeringsomgivelser for Java testAddDays Ny klasse Skal indeholde vores tests for Date klassen Er "bundet fast" til Date klassen og flytter sig sammen med denne Knapper til optagelse og afspilning af tests Den røde plet viser, at vi er i gang med en optagelse Test systemet husker de metodekald, som vi laver Gøres synlige via Interface fanebladet i Preference operationen i Tools menuen

9 Optagelse af test 3. Kald toString metoden på date1 objektet
Ny del, hvor vi kan definere en assertion, dvs. en betingelse som vi vil have systemet til at tjekke " " 4. Når vi ikke ønsker at udføre mere, afsluttes optagelsen Værdierne af feltvariablerne opdateres 10 1. Lav et Date objekt 2. Kald addDays metoden

10 Den optagne testmetode
I DateTest klassen er der tilføjet en ny metode Markeret Indeholder Java kode, der udfører de tre ting vi gjorde under optagelsen Lav et Date objekt ( ) Kald addDays metoden med parameteren 10 Kald toString metoden og tjek, at den returnerer det forventede resultat (strengen" ")

11 Kørsel af testmetode Vi kan nu køre test metoden, ved at kalde TestAll operationen for klassen DateTest Hvis vi vil ændre i den optagne metode kan vi Lave en helt ny optagelse Modificere Java koden i klassen DateTest 10  20 " " Stadig OK 10  –3 " " ERROR

12 Beskrivelse af hvad der gik galt
public void addDays(int d) { for(int i = 0; i<d; i++) { setToNextDate(); } Hvis parameteren er negativ udføres kroppen af for løkken slet ikke Når man har lavet et par optagelser af test metoder og set, hvordan de ser ud, er det langt hurtigere at skrive test metoderne selv – i stedet for at optage dem Bemærk:

13 Regressions tests Forberedelser
For hver af klassens metoder laves en eller flere testmetoder Disse kan enten optages, eller man kan kode dem direkte i Java Det sidste er forholdsvis let, hvis testmetoden ligner en tidligere Man bruger ofte de samme objekter i mange testmetoder Man kan så (en gang for alle) lave en såkaldt test fixture, der indeholder de pågældende objekter Fixture betyder "fast inventar" – detaljer er forklaret i afsnit Hver gang man ændrer en eller flere af klassens metoder Kører man alle testmetoderne – ved ét enkelt tryk på TestAll / Run Tests Man kan på få millisekunder se, om alt stadig fungerer som forventet Hvis der findes fejl, skal man overveje, om det er den fejlende metode, der skal ændres, eller det er den angivne assertion, der er forkert Det sidste kan f.eks. være tilfældet, hvis man har ændret en metode til at kunne håndtere specielle input værdier på mere fornuftig vis, f.eks. hvis man har ændret addDays til at kunne få tiden til at gå baglæns (ved negative parameter værdier)

14 Kan regressions tests betale sig?
Ulemper Det tager en del tid at lave de mange testmetoder Fordele Fejl introduceret på grund af koderettelser findes langt hurtigere og med langt større sandsynlighed Senere kan sådanne fejl være virkelig svære at finde, idet fejlen måske er opstået da man rettede "noget helt andet" Man slipper for kedelige manuelle tests Konklusion Brug tid på (helt fra start) at udvikle test metoder, der kan fungere i forbindelse med automatiske regression tests Det betaler sig i det lange løb – også for metoder, der tilsyneladende er forholdsvis simple Pause

15 ● Debugging (aflusning, fjernelse af fejl)
BlueJ bogen introducerer tre teknikker til debugging Manual gennemgang af koden Brug af BlueJ's debugger Brug af print sætninger Ideen i de tre er teknikker er den samme Under udførslen af koden, inspicerer man værdierne af udvalgte variabler hvordan metoderne kalder hinanden Forskelle mellem teknikkerne Ved en manual gennemgang klarer man alle beregninger selv. Det tager lang tid og man kan let lave fejl BlueJ's debugger holder styr på variablernes værdier og hvilke metoder der er på kontrolstakken. Det sparer tid og debuggeren laver aldrig fejl Men det kræver lidt tid og kræfter, at lære at bruge debuggeren Print sætninger er en mellemting. Tingene beregnes automatisk, men hvis man vil se værdierne af nye variabler må man manuelt ind og tilføje nye print sætninger Derudover er det mere besværligt at slå print sætninger til og fra

16 BlueJ's debugger (kort repetition)
Nyttig når man skal tjekke den detaljerede opførsel af kørende Java kode Breakpoints indsættes (og fjernes) ved at klikke i venstre margin af editoren Under programudførelsen vil debuggeren stoppe, når et breakpoint nås, og vise positionen med en sort pil (samt gul farve) Herefter kan man ”steppe” gennem koden sætning for sætning

17 Metodekald Når næste sætning er et metodekald, har man to muligheder:
Udfører hele metodekaldet uden at man ser detaljerne Starter metode-kaldet, men stopper ved første instruktion i den kaldte metode

18 Metodekald Parat til at udføre første sætning i den kaldte metode
Andre knapper: Fortsætter kørslen frem til næste breakpoint Stopper kørslen Nødstop (uendelig while løkke eller lignende)

19 Undervejs kan man inspicere
Igangværende metodekald Værdier for feltvariabler Værdier for lokale variabler

20 Debugging af funktionel kode
Lambda'er og streams kan debugges som al anden kode peek metoden gør det nemt at lave print sætninger Intermediate metode, hvor output stream er identisk med input stream Undervejs kan vi f.eks. udskrive elementerne public long findSumOfAgeOfTeenagers() { return persons.stream() .peek( elem -> print("Start: " + elem )) .filter( elem -> (13 <= elem.getAge())) .peek( elem -> print("13 <=: " + elem)) .filter( elem -> (elem.getAge() <= 19)) .peek( elem -> print("19 >=: " + elem)) .mapToInt( elem -> elem.getAge()) .peek( elem -> print("mapToInt: " + elem)) .sum(); } public long findSumOfAgeOfTeenagers() { return persons.stream() .filter( elem -> (13 <= elem.getAge())) .filter( elem -> (elem.getAge() <= 19)) .mapToInt( elem -> elem.getAge()) .sum(); } private void print(Object o) { System.out.println(o); }

21 Test og debugging Alle programmer indeholder fejl
Anvendelse af gode software udviklingsteknikker (indkapsling, sammenhæng og løs kobling) reducerer antallet af fejl Test bør blive en vane Automatiser test så meget som muligt Husk regression test, når I modificerer kode Øv jer i at bruge forskellige teknikker til debugging Automatiser debugging så meget som muligt BlueJ's debugger er et fortrinligt værktøj hertil Jeg vil ikke gennemgå de tre debugging teknikker De egner sig ikke til gennemgang på slides Læs om dem i BlueJ bogen Afprøv dem i praksis Også de mere avancerede teknikker såsom brug af BlueJ's debugger Den kan I med fordel bruge i nogle af de kommende afleveringsopgaver

22 ● StringBuilder klassen (fra java.lang)
Alternativ til konkatenation af strenge ved hjælp af + operatoren Lad os, som et eksempel, lave en toString metoden for Post klassen public String toString() { StringBuilder builder = new StringBuilder(); builder.append(username); builder.append(timeString( timestamp )); if( likes > 0) { builder.append(likes + " people like this."); } else { builder.append('\n'); if( comments .isEmpty()) { builder.append("No comments."); builder.append(comments.size() + " comment(s)."); return builder.toString(); public String toString() { StringBuilder builder = new StringBuilder(); builder.append(username); builder.append(timeString( timestamp )); if( likes > 0) { builder.append(likes + " people like this."); } else { builder.append( '\n' ); if( comments.isEmpty()) { builder.append("No comments."); builder.append(comments.size() + " comment(s)."); return builder.toString(); Lokal variabel af type StringBuilder Tilføj de ønskede strenge ved hjælp af append metoden i StringBuilder Linjeskift Returner den opbyggede streng ved hjælp af toString metoden i StringBuilder

23 ● Projektopgave om computerspil
I kursets sidste fem uger skal I, sammen med en makker, programmere et computerspil Den sidste af ugens øvelsesgange bruges på projektopgaven Hver uge tilføjer I ting, som I har lært om i den foregående uge(r) De fem delafleveringer tæller tilsammen med ca. 30% i den endelige karakter for kurset For hver godkendt delaflevering får man op til 6 point 6 = fremragende (≈ 12) 5 = fortrinlig (≈ 10) 4 = god (≈ 7) – få mindre mangler (rettes i næste delaflevering) 3 = jævn (≈ 4) – nogle mindre mangler (rettes i næste delaflevering) 2 = tilstrækkelig (≈ 02) – mange fejl (rettes i genaflevering) Hvis man skal genaflevere, kan man højst få 2 point Det samme er tilfældet, hvis man afleverer for sent (uden gyldig grund)

24 ● Afleveringsopgave: Computerspil 1
I skal programmere et computerspil, hvor spillerne rejser rundt mellem byer i forskellige lande og indsamler point I første delaflevering skal I bl.a. modellere byerne og vejene imellem dem, samt de lande byerne ligger i. Når I er færdige, vil I kunne spille Der er forholdsvis meget at lave, men langt de fleste af tingene er lette at implementere. En af instruktorerne lavede en løsning på ca. 30 minutter For at spare tid må I rent undtagelsesvis vente med at dokumentere de klasser, konstruktører og metoder, som I skriver

25 Brug af Test Fixture Når man skal afteste metoderne i Country og City klasserne, har man behov for at kunne skabe Country objekter Dette er lidt bøvlet, idet klassens konstruktør har en parameter af typen Map<City, List<Road>> En første løsning er at bruge null som parameterværdi En mere sofistikeret løsning er at bruge en Test Fixture som realiserer nedenstående netværk Test Fixturen kan kopieres til Object benchen, som så får nedenstående udseende Opgaveformuleringen forklarer, hvordan Test Fixturen hentes og anvendes

26 Computerspil 2-5 I de næste fire delafleveringer skal I
Dokumentere jeres klasser, konstruktører og metoder samt lave regression tests for alle konstruktører og metoder (Computerspil 2). Bruge nedarvning (subklasser) og dynamisk method binding (overskrivning af metoder) til at strukturere jeres kode, således at der er flere forskellige slags lande og flere forskellige slags byer (Computerspil 3). Udvide den grafiske brugergrænseflade med nogle ekstra knapper, labels og tekstfelter (Computerspil 4). Lave automatisk logning af et spil, ved at gemme en passende tekstfil, som så senere kan genindlæses og afspilles for at genskabe det optagne spil (Computerspil 5).

27 ● Opsummering Opremsningstyper
Enumerated types Forskellige teknikker til test og debugging Når man tester undersøger man, om opførslen (semantikken) er den ønskede Når man debugger (afluser), forsøger man at finde ud af, hvorfor opførslen ikke er, som man ønskede og forventede StringBuilder klassen Opbygning af lange tekststrenge Projektopgave om computerspil I kursets sidste fem uger skal I, sammen med en makker, programmere et computerspil Der er fem delafleveringer og de indgår tilsammen med ca. 30% i den endelige karakter for kurset

28 Det var alt for nu….. … spørgsmål


Download ppt "Forelæsning Uge 10 – Torsdag"

Lignende præsentationer


Annoncer fra Google