LUNDS TEKNISKA HÖGSKOLA EDAA01 Programmeringsteknik fördjupningskurs Institutionen för datavetenskap HT 2015



Relevanta dokument
Institutionen för datavetenskap HT /2008. Testning med JUnit

JUnit 4 - användning. Grunderna. org.junit. org.junit.test. Henrik Bergström DSV SU/KTH. Innehåller bland annat:

NetBeans 5.5. Avsikt. Projektfönster

Länkade listor och automatisk testning

Föreläsning 3 Innehåll. Generiska klasser. Icke-generisk lista ArrayList, skiss av implementering. Icke-generisk lista Risk för fel

NetBeans 7. Avsikt. Projektfönster

Lite om felhantering och Exceptions Mer om variabler och parametrar Fält (eng array) och klassen ArrayList.

Grundkurs i programmering, 6 hp (725G61) Dugga 2 tillfälle 2

Eclipse. Avsikt. Nu ska ett fönster liknande figuren till höger synas.

LÖSNINGSFÖRSLAG Programmeringsteknik För Ing. - Java, 5p

Laboration 10 - Eclipse

Föreläsning 5-6 Innehåll. Exempel på program med objekt. Exempel: kvadratobjekt. Objekt. Skapa och använda objekt Skriva egna klasser

Versionshantering. Jan Erik Moström

Chapter 4: Writing Classes/ Att skriva egna klasser.

Föreläsning 5-6 Innehåll

Eclipse en handledning

KARLSTADS UNIVERSITET 12/8/09 informatik & datavetenskap Johan Öfverberg, Kerstin Andersson Laboration 4, ISG A04 och DVG A08 HT-09

Testning av program. Verklig modell för programutveckling

Övningsuppgift. Bankkonton. Steg 2. Författare: Mats Loock Kurs: Inledande programmering med C# Kurskod:1DV402

1 Uppgift 1. a) Skapar ett Company-objekt med hjälp av den överlagrade konstruktorn. Du kan själv välja värden på instansvariablerna.

JUnit. Junit Unit Testing. JUnit 3. JUnit 3 forts. Villkorskontroller i test. Exempel JUnit3

Bankkonto - övning. Övning 2 Skriv en metod, geträntan, som returnerar räntan.

Föreläsnings 9 - Exceptions, I/O

Det finns en referensbok (Java) hos vakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Diagnostiskt Prov. Antaganden Om förutsättningar saknas I en uppgift skall rimliga antaganden göras och nedtecknas.

Arv: Fordonsexempel. Arv. Arv: fordonsexempel (forts) Arv: Ett exempel. En klassdefinition class A extends B {... }

2D1311 Programmeringsteknik för Bio1 och Bio2, vt 2003 Fiktivt prov På flervalsfrågorna är endast ett svar rätt om inget annat anges i frågan! Det rik

Att skriva till och läsa från terminalfönstret

Föreläsning 8 - del 2: Objektorienterad programmering - avancerat

Laboration 10 - NetBeans

Objektsamlingar i Java

Att öva på och förstå ett program med flera samverkande klasser.

Dagens program. Programmeringsteknik och Matlab. Objektorienterad programmering. Vad är vitsen med att ha både metoder och data i objekten?

Här beskrivs Eclipse, den programutvecklingsmiljö som utnyttjas i programmeringskurserna. Mera information finns på:

Tentamen i Objektorienterad modellering och design

TENTAMEN: Objektorienterad programmering. Läs detta! Skriv din tentamenskod på varje blad (så att vi inte slarvar bort dem).

Föreläsning 4 Innehåll. Abstrakta datatypen lista. Implementering av listor. Abstrakt datatypen lista. Abstrakt datatyp

TDA550 Objektorienterad programvaruutveckling IT, forts. kurs Övning vecka 2

Det finns en referensbok (Java) hos vakten som du får gå fram och läsa men inte ta tillbaka till bänken.

Design av en klass BankAccount som representerar ett bankkonto

Objektorienterad programmering i Java Undantag Sven-Olof Nyström Uppsala Universitet Skansholm: Kapitel 11

Idag. Exempel, version 2. Exempel, version 3. Ett lite större exempel

Laboration 13, Arrayer och objekt

Idag. statiska metoder och variabler. private/public/protected. final, abstrakta klasser, gränssnitt, delegering. wrapper classes

Några principer för effektiv enhetstestning

Ett problem. Kontrollstrukturer och arrayer. Arrayer. Lösningen. Arrayer och hakparanteser. Exempel int[] results; results = new int[10]; // 0..

DIAGNOSTISKT PROV. Tid. Hjälpmedel. Antaganden. Rättning. Övrigt. Diagnostiskt Prov. Klockan Inga

Föreläsning 2 Objektorienterad programmering DD1332. Typomvandling

Java: kort introduktion. Trådar. Något om mutex, Dekkers algoritm och monitorer. Javas ("inbyggda monitor") synchronized.

PROGRAMMERINGSTEKNIK TIN212

Uppgiften är att beskriva en kvadrat i ett Java program. En första version av programmet skulle kunna se ut så här:

TENTAMEN PROGRAMMERINGSMETODIK MOMENT 2 - JAVA, 4P

Det är principer och idéer som är viktiga. Skriv så att du övertygar examinatorn om att du har förstått dessa även om detaljer kan vara felaktiga.

TENTAMEN I PROGRAMMERING. På tentamen ges graderade betyg:. 3:a 24 poäng, 4:a 36 poäng och 5:a 48 poäng

Objektorienterad programmering i Java Undantag Sven-Olof Nyström Uppsala Universitet Skansholm: Kapitel 11

TDA550 Objektorienterad programvaruutveckling IT, forts. kurs Övning vecka 3

Föreläsning 4 Innehåll

Föreläsning 3-4 Innehåll. Diskutera. Metod. Programexempel med metod

Laboration A Objektsamlingar

Föreläsning 5 (6) Metoder. Metoder Deklarera. Metoder. Parametrar Returvärden Överlagring Konstruktorer Statiska metoder tostring() metoden javadoc

DAT043 - Föreläsning 7

Tentamen ID1004 Objektorienterad programmering October 29, 2013

TDDC30 Programmering i Java, Datastrukturer och Algoritmer Lektion 2. Länkade listor Stackar Köer MyList Iteratorer Lab 2 Exceptions Paket

Arrayer. results

Föreläsning 3-4 Innehåll

Tentamen, EDAA10 Programmering i Java

Övningsuppgift 8, Mer om enhetstest

Kompilering och exekvering. Föreläsning 1 Objektorienterad programmering DD1332. En kompilerbar och körbar java-kod. Kompilering och exekvering

TENTAMEN PROGRAMMERING I JAVA, 5P SOMMARUNIVERSITETET

Tentamen, EDA501 Programmering M L TM W K V

Enkla variabler kontra referensvariabel

Läs detta! Uppgifterna är inte avsiktligt ordnade efter svårighetsgrad. Skriv ditt idnummer på varje blad (så att vi inte slarvar bort dem).

TDDC74 Programmering: Abstraktion och modellering Datortenta

Lösningsförslag till omtentamen för TDA540 Objektorienterad Programmering

Föreläsning 3 Innehåll

Diskutera Sortera objekt

Tentamen. Programmeringsmetodik, KV: Java och OOP. 17 januari 2002

Objektorienterad Programkonstruktion. Föreläsning jan 2016

Testning och felhantering

Kompilera och exekvera Javakod

Tentamen, EDA690 Algoritmer och Datastrukturer, Helsingborg

Objektorienterad Programkonstruktion. Föreläsning 2 2 nov 2016

Repetition av OOP- och Javabegrepp

Classes och Interfaces, Objects och References, Initialization

Kort om klasser och objekt En introduktion till GUI-programmering i Java

public static void mystery(int n) { if (n > 0){ mystery(n-1); System.out.print(n * 4); mystery(n-1); } }

Överlagring, static, testning, formella metoder och undantag! Förelasning 13!! TDA540 Objektorienterad Programmering!

Tentamen. Grundläggande programmering i Java A 5p, DTAA

Mer om klasser och objekt

Högskolan Dalarna sid 1 av 7 DI-institutionen Hans-Edy Mårtensson Sten Sundin

Exempel. Arrayer. Lösningen. Ett problem. Arrayer och hakparanteser. Arrayer

Anmälningskod: Lägg uppgifterna i ordning. Skriv uppgiftsnummer (gäller B-delen) och din kod överst i högra hörnet på alla papper

Testramverk och Model based testing med java i praktiken

Repetition av OOP- och Javabegrepp

Lösningar till tentamen i EDAF25

Kort repetition. Programmeringsteknik för Bio1 och I1. Vad ska vi lära oss idag? Ett exempel

Tentamen i EDAF25. 1 juni Skrivtid: Skriv inte med färgpenna enda tillåtna färg är svart/blyerts.

Tentamen, EDA501 Programmering M L TM W K V

Att använda Java SE JDK 6

Programmering med Java. Grunderna. Programspråket Java. Programmering med Java. Källkodsexempel. Java API-exempel In- och utmatning.

Transkript:

LUNDS TEKNISKA HÖGSKOLA EDAA01 Programmeringsteknik fördjupningskurs Institutionen för datavetenskap HT 2015 Testning med JUnit 1 Inledning JUnit är ett ramverk för enhetstestning av Javakod. Det är utvecklat av Kent Beck och Erich Gamma. Här beskrivs hur man använder verktyget JUnit för att testa de klasser man skriver. Mera information finns på: https://github.com/junit-team/junit/wiki/ http://junit.org/javadoc/latest/ 2 Enhetstestning När man implementerat en klass måste man, innan den kan användas, testa att den uppfyller sin specifikation. Denna typ av testning brukar kallas enhetstestning. Vid s.k. black-box testning ser man en klass som en svart låda d.v.s. man vet ingenting om hur metoderna är implementerade. Det som testas är att metoderna ger det förväntade resultatet enligt sin specifikation. Antag t.ex. att vi har implementerat en klass som representerar ett bankkonto med följande specifikation: public class BankAccount { * Create new account with balance 0. public BankAccount(); * Returns balance of account * @return balance of account public int getbalance(); * Deposits the specified amount. * pre: The specified amount is >= 0 * post: The specified amount is added to balance * @param n The amount to deposit * @throws IllegalArgumentException if the specified amount is < 0 public void deposit(int n); * Withdraws the specified amount. * pre: The specified amount is >= 0 and <= balance

2 Enhetstestning * post: Balance is decreased by the specified amount * @param n The amount to withdraw * @throws IllegalArgumentException if the specified amount is < 0 * or > balance of account public void withdraw(int n); För att testa att en klass uppfyller sin specifikation måste man skriva programkod som anropar metoderna i olika situationer och kontrollera att resultatet blir det förväntade. Det är viktigt att man noga tänker igenom vilka olika fall som måste testas. För klassen BankAccount finns t.ex. följande fall som bör kontrolleras: getbalance() ska ge resultatet 0 för ett nyskapat konto deposit(n) följt av getbalance() ska ge resultatet n deposit(t1); withdraw(t2); ; deposit(tn); (med legala parametervärden för uttag) följt av getbalance() ska ge resulatet t1-t2+tn withdraw(n) ; där n > getbalance() ska generera IllegalArgumentException. De nämnda testfallen är bara en delmängd av alla fall som måste testas för att man ska veta att klassen uppfyller sin specifikation. Det är viktigt att testfallen också omfattar onormala fall och gränsfall. För bankkontoklassen är ett sådant fall att man försöker ta ut mer pengar än vad som finns. Enligt specifikationen ska då IllegalArgumentException genereras. Ytterligare onormala fall är att försöka sätta in eller ta ut ett negativt belopp. För en klass som hanterar listor kan intressanta gränsfall vara att ta bort det enda elementet i en lista eller att sätta in ett element allra först eller sist i listan. 2.1 Enhetstestning med JUnit i Eclipse Ett sätt att genomföra testning enligt ovan är att skriva en main-metod i den klass som ska testas och låta den innehålla de kombinationer av metodanrop som motsvarar de olika testfallen. För att förenkla testförfarandet, speciellt när många klasser ska enhetstestas, kan man ha hjälp av ett verktyg. Vi ska här beskriva ett sådant verktyg, JUnit. I JUnit kan man samla alla test som rör en viss klass i en testklass och utföra alla tester och få en grafisk presentation av resultatet. Till varje klass som ska testas med hjälp av JUnit skriver man en motsvarande testklass som kan se ut så här: import static org.junit.assert.*; import org.junit.after; import org.junit.before; import org.junit.test; public class TestMyClass { @Before public void setup() { @After public void teardown() {

Enhetstestning 3 public final void testxxx() { public final void testyyy() { Metoderna setup och teardown är annoterade med @Before respektive @After. Metoder med dessa annotationer anropas av ramverket före, respektive efter varje test i testklassen. I setup kan man därför initiera det tillstånd man vill utgå ifrån i varje testfall, t.ex. skapa en instans av den klass som ska testas. I teardown kan man städa upp efter varje test t ex genom att frigöra resurser som man allokerat i setup. Det är inte nödvändigt att ha med metoderna setup och teardown. Man kan i stället skapa instans(er) av den klass man vill testa i varje enskild testmetod. För varje test man vill utföra skriver man en metod som annoteras med. Dessa metoder kommer att köras av ramverket. Metoderna testxxx, testyyy, i exemplet ovan ska alltså innehålla de sekvenser av metodanrop som motsvarar testfall man vill genomföra. Observera att testmetoderna måste vara publika för att ramverket ska kunna anropa dem. För att informera testramverket om utfallet finns ett antal statiska metoder i ett paket org. junit.assert. Dessa kan användas i testmetoderna för att kontrollera att resultat efter anrop av metoder är det förväntade. En del av dessa metoder räknas upp nedan. För fullständig förteckning se dokumentationen av klassen Assert se dokumentation an junit på nätet. asserttrue(string message, boolean condition) assertequals(string message, TYPE expected, TYPE actual); assertnotnull(string message, Object obj); assertnull(string message, Object obj); assertsame(string message, Object expected, Object actual); fail(string message); Assert betyder ungefär att hävda, påstå. I metoderna ovan är message det meddelande som används för att generera felmeddelande i det grafiska gränssnittet vid körning av testfallet om utfallet inte är det förväntade. TYPE är någon av typerna boolean, byte, int, short, long, float, double eller Object. Om påståendena inte är sanna så genererar ramverket meddelanden om att testfallet inte gav förväntat resultat. fail-metoden används när man utan att behöva kontrollera någonting vet att man misslyckats. 2.2 Exempel på testklass i JUnit 4 Vi visar som exempel test av bankkontoklassen med hjälp av JUnit. Vi utgår ifrån att vi har ett projekt i Eclipse med klassen BankAccount enligt ovan. Man skapar en testklass på följande sätt i Eclipse: 1. Markera med högerknappen det paket där du vill placera testklassen och välj New -> JUnit Test Case. Då öppnas ett dialogfönster. 2. Överst i dialogfönstret finns knappar för att välja om man vill skapa en testklass för en äldre version av JUnit eller en testklass för den senaste versionen JUnit 4. Markera JUnit 4. 3. Fyll i det namn du vill ge din testklass, t ex BankAccountTest, i textrutan Name.

4 Enhetstestning 4. Kryssa i att du vill generera metoderna setup() och teardown(). 5. Fyll i namnet på den klass som ska testas. Om denna klass befinner sig i ett annat paket i projektet måste du kvalificera namnet med paketets namn. Om du valt att placera en testklass för bankkontoklassen (som finns i paketet bank) i ett annat paket i projektet anger du alltså bank.bankaccount. Om du valt att ha testklassen i samma paket som klassen BankAccount behöver du bara ange BankAccount 6. Klicka på Next i dialogfönstret 7. Markera de metoder i BankAccount du vill testa, vilket vanligtvis är alla metoder. 8. Klicka på Finish. 9. Om det är den första testklassen som skapas i projektet så kommer det att öppnas ett nytt dialogfönster med texten JUnit 4 is not on the build path. Do you want to add it?. Låt alternativet perform the following action: Add JUnit library to the build path vara markerad och klicka på OK. Då stängs dialogfönstren. Nu öppnas din nyskapade testklass i editorn. Det finns stubbar för metoderna setup och teardown. Dessutom finns det stubbar för ett antal testmetoder, en för varje metod i klassen BankAccount, som du markerat enligt punkt 7 ovan. Man vill naturligtvis i allmänhet ha mer än en test av varje metod i den klass som ska testas. Ytterligare test skapas enkelt genom att kopiera en testmetod, klistra in kopian i testklassen och byta dess namn och innehåll. Alla testmetoder innehåller en rad: fail("not yet implemented"); Denna rad ska ersättas med din egen testkod. Redan innan du gör detta kan du köra testen. Markera tesklassen med högerknappen och välj Run As -> JUnit Test. Följande klass innehåller testmetoder motsvarande några av de fall som behöver testas: import static org.junit.assert.*; import org.junit.after; import org.junit.before; import org.junit.test; public class BankAccountTest { private BankAccount theaccount; @Before public void setup() throws Exception { theaccount = new BankAccount(); @After public void teardown() throws Exception { theaccount = null; public final void testgetbalance() { assertequals("new account, balance not 0", 0, theaccount.getbalance()); public final void testdeposit() { theaccount.deposit(100);

Prova JUnit 5 assertequals("wrong balance after deposit", 100, theaccount.getbalance()); public void testwithdraw() { theaccount.deposit(100); theaccount.withdraw(20); assertequals("wrong balance after withdraw", 80, theaccount.getbalance()); theaccount.withdraw(80); assertequals("wrong balance after withdraw", 0, theaccount.getbalance()); (expected=illegalargumentexception.class) public final void testoverdraft() { theaccount.deposit(100); theaccount.withdraw(200); I testklassen deklareras ett attribut theaccount som är det konto som testas. I metoden setup skapas före varje test ett nytt konto som theaccount refererar till. I teardown tas det bort (egentligen onödigt här eftersom setup ändå skapar ett nytt före nästa test). Den första testen testgetbalance kontrollerar att ett nytt konto har behållningen 0. Om så inte är fallet kommer ett meddelande New account. att visas av ramverket. Metoden testdeposit kontrollerar att behållningen är korrekt efter en enda insättning. Lägg märke till hur det sista testet testoverdraft testar om det verkligen genereras Exception vid försök till att ta ut för mycket pengar. Annotationen har i detta fall fått attributet expected med värdet IllegalArgumentException.class. Om raderna i testoverdraft inte genererar IllegalArgumentException misslyckas testet. Man exekverar alla testmetoderna i testklassen BankAcounmtTest i Eclipse genom att markera klassen med högerknappen och välja Run As -> JUnit Test. Testresultatet visas i Eclipse enligt Fig. 1. När testen exekveras rapporterar JUnit vilket/vilka testfall som eventuellt gick fel. Härav kan man oftast dra slutsatser om vilken/vilka metoder det är i den testade klassen som är felaktiga. Skulle t ex testfallet testgetbalance ovan ge felmeddelande så måste något vara fel i antingen konstruktorn i BankAccount eller i metoden getbalance. Man får i så fall försöka korrigera och köra testerna på nytt tills man känner sig nöjd med funktionaliteten i klassen. Eventuellt kommer man under denna process på ytterligare test som bör utföras. I så fall får man komplettera testklassen med fler testmetoder. 3 Prova JUnit Det finns ett förberett arbetsområde för laborationerna som kan hämtas från kursens hemsida. I detta arbetsområde finns, förutom de sex laborationsprojekten, ett projekt med namnet banktest, som innehåller en färdig implementering av bankkontoklassen och dess testklass enligt ovan. Exekvera BankAccountTest genom att markera klassen och välja Run As -> JUnit Test. Alla tester går igenom. Verktyget rapporterar att 4 Runs genomförts (det finns fyra testmetoder i klassen BankAccountTest) samt att antalet Failures och Errors är 0. Dessutom visas grönt ljus. Se Fig. 1. JUnit skiljer mellan två sorters fel; Failures och Errors. Failures är den typ av fel som upptäcks genom assert-satserna. Errors är oförutsedda fel som kan bero på att man skrivit kod som leder till exekveringsfel i klassen som testas eller i testmetoderna, t.ex. råkar ut för att få ArrayIndexOutOfBoundsException eller dylikt.

6 JUnit utanför Eclipse Figur 1: Resultat efter exekvering av 4 test avseende klassen BankAccount För att få se hur det blir när test går fel kan du introducera något fel i klassen BankAccount. Låt t.ex. tillgången på ett nyskapat konto bli 100 genom att ändra i konstruktorn i klassen. Kör sedan testerna på nytt. Nu rapporteras inte mindre än 4 failures. Se Fig 2. Alla fyra testen ger fel resultat. Genom att markera ett av de test som gått fel får man i den undre textrutan det genererade felmeddelandet för den markerade metoden. Man får också uppgift om på vilken rad felet inträffat. Dubbelklickar du på raden som anger var felet inträffat så markeras motsvarande rad i testklassen i editorfönstret. 4 JUnit utanför Eclipse JUnit kan också användas utanför Eclipse. Information om hur man gör finns på webbsidan https://github.com/junit-team/junit/wiki/test-runners.

JUnit utanför Eclipse 7 Figur 2: Testklassen BankAccountTest med 4 testfall har körts. Fyra fel (failures) rapporteras. Det första test som gick fel är markerat (testgetbalance). Ett meddelande som genererats från assert-satsen i testnewaccount visas i den undre textrutan tillsammans med en uppgift om på vilken rad felet inträffade.