37
11. Tema Testiranje Objektno orijentirano programiranje 12/4/16 Zaštićeno licencom http://creativecommons.org/licenses/by-nc-sa/3.0/hr/

Objektno orijentirano programiranje

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Objektno orijentirano programiranje

11. TemaTestiranje

Objektno orijentirano programiranje

12/4/16 Zaštićeno licencom http://creativecommons.org/licenses/by-nc-sa/3.0/hr/

Page 2: Objektno orijentirano programiranje

Creative Commons

slobodno smijete:

dijeliti — umnožavati, distribuirati i javnosti priopćavati djelo

remiksirati — prerađivati djelo

pod sljedećim uvjetima:

imenovanje. Morate priznati i označiti autorstvo djela na način kako je specificirao autor ili davatelj licence (ali ne način koji bi sugerirao da Vi ili Vaše korištenje njegova djela imate njegovu izravnu podršku).

nekomercijalno. Ovo djelo ne smijete koristiti u komercijalne svrhe.

dijeli pod istim uvjetima. Ako ovo djelo izmijenite, preoblikujete ili stvarate koristeći ga, preradu možete distribuirati samo pod licencom koja je ista ili slična ovoj.

12/4/16

U slučaju daljnjeg korištenja ili distribuiranja morate drugima jasno dati do znanja licencne uvjete ovog djela. Najbolji način da to učinite je linkom na ovu internetsku stranicu. Od svakog od gornjih uvjeta moguće je odstupiti, ako dobijete dopuštenje nositelja autorskog prava. Ništa u ovoj licenci ne narušava ili ograničava autorova moralna prava.

Tekst licencije preuzet je s http://creativecommons.org/.

Objektno orijentirano programiranje, FER 2 / 34

Page 3: Objektno orijentirano programiranje

Općenito o testiranju programskog koda

Testiranje programa Izvođenje programskog koda skupom ulaznih podataka

Cilj testiranja Pronaći neispravnosti programskog koda Test je dobar ako njegovo izvođenje prouzroči ispad programa

Odabir test uzoraka Program ne možemo testirati svim mogućim ulaznim podacima (tzv. iscrpno

testiranje) Odabiremo mali skup reprezentativnih ulaznih podataka

Objektno orijentirano programiranje, FER 12/4/16 3 / 34

Page 4: Objektno orijentirano programiranje

Osnovni pojmovi

Testna jedinica (implementation under test) Programska cjelina koja se testira

Test uzorak (test case) Element ulazne domene koji omogućuje jedno samostalno izvođenje testne

jedinice Zbirka test uzoraka (test suite)

Skup test uzoraka koji su povezani u grupu na osnovu cilja testiranja ili implementacijske povezanosti

Debugging Analiza koda radi lokaliziranja i otklanjanja neispravnosti

Objektno orijentirano programiranje, FER 12/4/16 4 / 34

Page 5: Objektno orijentirano programiranje

Testiranje jedinica

Ponavljajuće testiranje malih jedinica kôda u izolaciji Jedinica koda je najčešće metoda ili skup vrlo sličnih metoda

Ukoliko je potrebno radimo imitiranje (mocking) drugih jedinica kôda Ostale vrste testiranja

Integracijskim testiranjem testiramo ispravan rad više komponenti pri zajedničkoj interakciji

Alfa i beta testiranje – prije završne isporuke, proizvod testira odabrana skupina korisnika

– Alfa testiranje – interno (zaposlenici tvrtke koja je razvila proizvod)– Beta testiranje – vanjski korisnici

Testiranje prihvatljivosti (acceptance test) – testiramo sustav u odnosu na zahtjeve naručitelja

Objektno orijentirano programiranje, FER 12/4/16 5 / 34

Page 6: Objektno orijentirano programiranje

Osnovni koraci testiranja

1. Definiranje skupa testnih uzoraka za testiranje programskog sustava

2. Izvođenje sustava odabranim uzorcima i detekcija eventualnih ispada

3. Ako je opažen ispad, slijedi analiza koda i otkrivanje neispravnosti u kodu (debugging)

4. Uklanjanje neispravnosti (mijenjanje koda)5. Ponovno izvođenje testova prethodno definiranim test uzorcima

(regresijsko testiranje)6. U slučaju ispada ponoviti korake 3., 4. i 5.

Objektno orijentirano programiranje, FER 12/4/16 6 / 34

Page 7: Objektno orijentirano programiranje

Alati za testiranje jedinica

xUnit je zajedničko ime za programske okvire (framework) za testiranje jedinica koji su nastali na osnovu okvira SUnit razvijenog za SmallTalk

Osnovne odrednice programskih okvira xUnit Izvođač testova (test runner) je izvršni program koji izvodi testove i prikazuje rezultate

njihova izvođenja Test (test case) je temeljni razred iz kojeg su izvedeni svi jedinični testovi Kontekst testa (test fixture ili test context) su preduvjeti (tj. stanje) potrebni za izvođenje

testa Skup testova (test suite) čine svi testovi koji zahtijevaju identičan kontekst Izvođenje testa

– Priprema: postavljanje okruženja za testiranje– Izvršavanje: pokretanje testa– Validacija: usporedba dobivenih s očekivanim rezultatima– Čišćenje: vraćanje okruženja u stanje koje je prethodilo testiranju

Formatiranje rezultata (result formatter) u jedan ili više izlaznih formata Tvrdnje (assertions) su logički uvjeti koje bi ispravna jedinica koda trebala zadovoljavati

Objektno orijentirano programiranje, FER 12/4/16 7 / 34

Page 8: Objektno orijentirano programiranje

JUnit

Javin programski okvir za testiranje jedinica Glavna ideja “Code a little, test a little” Autori su Erich Gamma i Kent Beck (koji je razvio i prethodno

spomenuti originalni SmallTalk-ov SUnit) JUnit definira testove (test cases) u odvojenim razredima te stoga

razdvaja testirajući (test class) od testiranog razreda (tested class) Različite verzije

Trenutno je aktualna inačica 4.12 koji uvelike koristi bilješke (annotations) Prethodna verzija 3 nije koristila bilješke Unatoč bilješkama, obje verzije su vrlo slične

U projekt je potrebno uključiti biblioteku za Junit (junit:junit:4.12, org.hamcrest:hamcrest-all:1.3)

Objektno orijentirano programiranje, FER 12/4/16 8 / 34

Page 9: Objektno orijentirano programiranje

Uključivanje biblioteke JUnit u projekt (ručno)

1. Dohvatiti datoteku junit.jar sa sljedeće adrese: https://github.com/junit-team/junit/wiki/Download-and-Install

2. Dohvatiti datoteku hamcrest-all.jar sa sljedeće adrese: https://storage.googleapis.com/google-code-archive-downloads/v2/code.google.com/hamcrest/hamcrest-all-1.3.jar

3. Dodati ih kao vanjske knjižnice (libraries) u projekt U Eclipse-u je dovoljno napraviti desni klik na jar, pa iz skočnog izbornika

odabrati Build path -> Add to build path. U NetBeans-u kliknite desnom tipkom na Libraries unutar aktivnog projekta

pa iz skočnog izbornika odaberite Add JAR/Folder.

Objektno orijentirano programiranje, FER 12/4/16 9 / 34

Page 10: Objektno orijentirano programiranje

Testirajući razred

Testirajući razred ima barem jednu testirajuću metodu Testirajuća metoda

standardana Javina metoda označena bilješkom @Test u JUnit4 mora biti javna (public) i ne smije vraćati ništa (void)

Prethodna inačica, JUnit 3, zahtijevala je da ime testirajuće metode počinje riječju „test” zbog bilješki to više nije nužno u inačici JUnit 4, ali se u praksi i dalje koristi zbog bolje preglednosti

Objektno orijentirano programiranje, FER 12/4/16 10 / 34

Page 11: Objektno orijentirano programiranje

Neobavezne metode testirajućeg razreda

U inačici JUnit 4 se one mogu bilo kako zvati, ali moraju biti označene bilješkama @Before i @After Metoda označena s bilješkom @Before se poziva točno jednom prije

izvođenja svake testirajuće metode Metoda označena s bilješkom @After se poziva točno jednom nakon

poziva svake testirajuće metode Ako imamo više metoda označenih bilješkama @Before ili @After, ne

znamo kojim će redoslijedom one biti pozivane Neobavezne metode su se u inačici JUnit 3 zvale setUp() i tearDown()pa se često tako nazivaju i danas

Metode označene bilješkom @BeforeClass odnosno @AfterClass, se izvršavaju samo jednom na početku odnosno kraju izvođenja testirajućeg razreda

Objektno orijentirano programiranje, FER 12/4/16 11 / 34

Page 12: Objektno orijentirano programiranje

Metode za definiranje tvrdnji

Potpuni popis ovih metoda: http://junit.org/junit4/javadoc/latest/org/junit/Assert.html Najčešće korištene tvrdnje

assertNull(Object x) – tvrdi da je objekt null assertNotNull(Object x) – tvrdi da objekt nije null assertTrue(boolean x) – tvrdi da je uvjet ispunjen assertFalse(boolean x) – tvrdi da uvjet nije ispunjen assertEqual(Object x, Object y) – tvrdi da su objekti jednaki (usporedba

operatorom equals) assertSame(Object x, Object Y) – tvrdi da su objekti identični (usporedba

operatorom ==) assertArrayEquals([] x, [] y) – tvrdi da su polja jednaka

Sve ove metode imaju i preopterećenu inačicu koja prima dodatni parametar tipa String koji predstavlja poruku koja će se ispisati ako tvrdnja ne bude stajala prilikom izvođenja testa

Objektno orijentirano programiranje, FER 12/4/16 12 / 34

Page 13: Objektno orijentirano programiranje

Stvaranje testirajućeg razreda i pokretanje testa u NetBeansu

Desnom tipkom kliknite na paket u kojem se nalazi razred koji želite testirati pa odaberite New -> Other -> Unit Tests -> JUnit Test te kliknite na gumb Next

Ime testirajućeg razreda je najčešće „imeTestneKlaseTest” te kliknite na gumb Finish

Ovime ste stvorili testirajući razred u direktoriju test (programski kôd je u direktoriju src)

Test pokrećete desnim klikom na testirajući razred i odabirom Run File ili Test File

Objektno orijentirano programiranje, FER 12/4/16

Rezultat testa se vidi u konzoli (tekstualni izvješće s detaljima) i posebnom prozoru Test Results (grafički prikaz)

13 / 34

Page 14: Objektno orijentirano programiranje

Stvaranje testirajućeg razreda i pokretanje testa u Eclipseu

Obično se testovi stavljaju u poseban direktorij test pa je potrebno napraviti novi source direktorij s imenom test: desni klik na projekt -> New -> Source Folder -> upišete test

Desnom tipkom kliknite na paket u kojem se nalazi razred koji želite testirati pa odaberite New -> Other -> Java -> JUnit -> JUnit Test Case, odaberite testirani razred pod Class under test: te kliknite na gumb Next

Ime testirajućeg razreda je najčešće „imeTestneKlaseTest”, odaberite novostvoreni Source Folder: test, te kliknite na gumb Finish

Test pokrećete desnim klikom na testirajući razred i odabirom Run As -> JUnit Test

Objektno orijentirano programiranje, FER 12/4/16

Rezultat testa se vidi posebnom prozoru Junit (grafički prikaz)

Greške pri izvođenju testa se vide u posebnom prozoru Failure Trace (tekstualni prikaz)

14 / 34

Page 15: Objektno orijentirano programiranje

Testiranje razreda StringBuilder

Napisat ćemo jedinične testove za razred StringBuilder da bi naučili kako se nešto može testirati

Za razliku od razreda String, ovaj razred modelira promjenjivi niz znakova

Glavne metode append – dodajemo niz znakova na kraj insert – umećemo niz znakova na odgovarajuću poziciju delete – brišemo znakove između dvije pozicije deleteCharAt – brišemo jedan znak na poziciji replace – s predanim znakovima zamjenjujemo znakove između dvije pozicije lastIndexOf – pronalazimo poziciju predanog niza znakova reverse – obrćemo sadržaj toString – dolazimo do sadržaja u obliku String-a

Objektno orijentirano programiranje, FER 12/4/16 15 / 34

Page 16: Objektno orijentirano programiranje

Prvi test razreda StringBuilder

Testiramo podrazumijevani konstruktor i metodu appendpublic class StringBuilderTest1 {

@Test public void testEmpty() { StringBuilder sb = new StringBuilder(); assertTrue(sb.toString().equals("")); assertTrue(sb.length() == 0); }

@Test public void testAppend() { StringBuilder sb = new StringBuilder(); sb.append("Some text"); assertEquals("Some text", sb.toString()); assertEquals(9, sb.length()); }}

Rezultati testa (izvješće)Testsuite: hr.fer.oop.topic13.example1.StringBuilderTest1Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 0.129 sec

Objektno orijentirano programiranje, FER 12/4/16

hr.fer.oop.testing.example1

16 / 34

Page 17: Objektno orijentirano programiranje

Drugi test razreda StringBuilder

Isti testovi kao i prije samo s greškamapublic class StringBuilderTest2 {

@Test

public void testEmpty() { StringBuilder sb = new StringBuilder(); assertTrue("contains something", sb.toString().equals("")); assertTrue("length not equal to: -1", sb.length() == -1); }

@Test public void testAppend() { StringBuilder sb = new StringBuilder(); sb.append("Some text"); assertEquals("text not equal to: S0me text", "S0me text", sb.toString()); assertEquals("length not equal to: 10", 10, sb.length()); }}

Objektno orijentirano programiranje, FER 12/4/16

hr.fer.oop.testing.example1

17 / 34

Page 18: Objektno orijentirano programiranje

Drugi test razreda StringBuilder

Rezultati (izvješće) testa StringBuilderTest2 (s greškama)

Testsuite: hr.fer.oop.topic13.example1.StringBuilderTest2Tests run: 2, Failures: 2, Errors: 0, Skipped: 0, Time elapsed: 0.189 sec

Testcase: testAppend(hr.fer.oop.topic13.example1.StringBuilderTest2): FAILEDtext not equal to: S0me text expected:<S[0]me text> but was:<S[o]me text>junit.framework.AssertionFailedError: text not equal to: S0me text expected:<S[0]me text> but was:<S[o]me text>

at hr.fer.oop.topic13.example1.StringBuilderTest2.testAppend(StringBuilderTest2.java:28)

Testcase: testEmpty(hr.fer.oop.topic13.example1.StringBuilderTest2):FAILEDlength not equal to: -1junit.framework.AssertionFailedError: length not equal to: -1

at hr.fer.oop.topic13.example1.StringBuilderTest2.testEmpty(StringBuilderTest2.java:21)

Test hr.fer.oop.topic13.example1.StringBuilderTest2 FAILED

Objektno orijentirano programiranje, FER 12/4/16

hr.fer.oop.testing.example1

18 / 34

Page 19: Objektno orijentirano programiranje

Treći test razreda StringBuilder

Test izaziva iznimkupublic class StringBuilderTest3 { @Test public void testProvokeException() { StringBuilder sb = null; sb.append("Some text"); assertEquals("Some text", sb.toString()); }}

Rezultati testa (izvješće)Testsuite: hr.fer.oop.topic13.example1.StringBuilderTest3Tests run: 1, Failures: 0, Errors: 1, Skipped: 0, Time elapsed: 0.137 sec

Testcase: testProvokeError(hr.fer.oop.topic13.example1.StringBuilderTest3): Caused an ERRORnulljava.lang.NullPointerException

at hr.fer.oop.topic13.example1.StringBuilderTest3.testProvokeError(StringBuilderTest3.java:19)

Test hr.fer.oop.topic13.example1.StringBuilderTest3 FAILED

Objektno orijentirano programiranje, FER 12/4/16

hr.fer.oop.testing.example1

19 / 34

Page 20: Objektno orijentirano programiranje

Metoda assertThat

Ova metoda također ima preopterećenu inačicu koja prima dodatni parametar tipa String koji predstavlja poruku koja će se ispisati ako tvrdnja ne bude stajala prilikom izvođenja testa

Dvije metode assertThat static <T> void assertThat(java.lang.String reason, T actual, org.hamcrest.Matcher<T> matcher)

static <T> void assertThat(T actual, org.hamcrest.Matcher<T> matcher)

Paket org.hamcrest.core dolazi s bibliotekom JUnit od inačice JUnit 4.4

Objektno orijentirano programiranje, FER 12/4/16 20 / 34

Page 21: Objektno orijentirano programiranje

Najkorisniji uspoređivači iz org.hamcrest.CoreMatchers

Osnovni uspoređivači static <T> Matcher<T> instanceOf(java.lang.Class<?> type) static <T> Matcher<T> equalTo(T operand) static <T> Matcher<T> sameInstance(T target) static Matcher<java.lang.Object> nullValue()

Dekoratori static <T> Matcher<T> allOf(Matcher<? super T>... matchers) static <T> AnyOf<T> anyOf(Matcher<? super T>... matchers) static <T> Matcher<T> is(Matcher<T> matcher) static <T> Matcher<T> not(Matcher<T> matcher)

Kratice static <T> Matcher<T> is(T value) => is(equalTo(value)) static <T> Matcher<T> not(T value) => not(equalTo(value)) static <T> Matcher<T> isA(java.lang.Class<T> type) => is(instanceOf(type))

static Matcher<java.lang.Object> notNullValue() => not(nullValue())

Objektno orijentirano programiranje, FER 12/4/16 21 / 34

Page 22: Objektno orijentirano programiranje

Prednosti korištenja uspoređivača Ulančavanje korištenjem obrasca dekorator (već smo ga vidjeli kod pod.tokova) Tvrdnje se puno lakše čitaju i razumljivije su

– assertFalse(expected.equals(actual));– assertThat(actual, is(not(equalTo(expected))));

Bolje su poruke o grešci assertTrue(expected.contains(actual)); – vraća se jedna vrijednost u poruci assertThat(actual, containsString(expected)); – vraćaju se obje vrijednosti u poruci

Možemo razviti vlastite uspoređivače Dodatni uspoređivači u knjižnici Hamcrest 1.3: http://

hamcrest.org/JavaHamcrest/javadoc/1.3/org/hamcrest/Matchers.html static Matcher<java.lang.String> containsString(java.lang.String substring)

static <E> Matcher<java.lang.Iterable<? extends E>> contains(E... items)

static <E> Matcher<E[]> arrayContaining(E... items) static Matcher<java.lang.Double> closeTo(double operand, double error)

…Objektno orijentirano programiranje, FER 12/4/16 22 / 34

Page 23: Objektno orijentirano programiranje

Potpuni test razreda StringBuilder s (dodatnim) uspoređivačima… @Test public void testEmpty() { assertThat(sb.toString(), is("")); assertThat(sb.length(), is(0)); }… @Test public void testAppend() { sb.append("Some text"); assertThat(sb.length(), is(9)); }… @Test public void testReplace() { sb.append("Some text"); sb.replace(5, 9, "characters"); assertThat(sb.toString(), not(containsString("text"))); assertThat(sb.toString(), containsString("characters")); assertThat(sb.toString(), is("Some characters")); assertThat(sb.length(), is(15)); } …

Objektno orijentirano programiranje, FER 12/4/16

hr.fer.oop.testing.example2

23 / 34

Page 24: Objektno orijentirano programiranje

Sučelje Dictionary, implement. MemoryDictionarypublic interface Dictionary { /** * U rječnik pohranjuje par originalna riječ - prijevod. * @param originalWord riječ koju treba prevesti * @param translatedWord prijevod */ public void add(String originalWord, String translatedWord); /** * Iz rječnika briše prijevod za prevedenu riječ. * @param deletedWord riječ čiji prijevod treba obrisati */ public void remove(String deletedWord); /** * Za predanu riječ dohvaća njen prijevod iz rječnika. * @param originalWord riječ koju treba prevesti * @return prijevod predane riječi */ public String get(String originalWord); /** * Vraća broj riječi koje imaju pohranjen prijevod u rječniku. * @return broj riječi u rječniku */ public int size(); }

Objektno orijentirano programiranje, FER 12/4/16

hr.fer.oop.testing.example3

24 / 34

Page 25: Objektno orijentirano programiranje

Test MemoryDictionaryTest

public class MemoryDictionaryTest {

private MemoryDictionary dictionary;

@Before public void setUp() { dictionary = new MemoryDictionary("knjiga", "book", "stvar", "thing"); }

@Test public void testGet() { assertThat(dictionary.get("knjiga"), is("book")); assertThat(dictionary.get("stvar"), is("thing")); }

@Test public void testAdd() { assertThat(dictionary.get("stol"), is(nullValue())); dictionary.add("stol", "table"); assertThat(dictionary.get("stol"), is("table")); }…

Objektno orijentirano programiranje, FER 12/4/16

hr.fer.oop.testing.example3

25 / 34

Page 26: Objektno orijentirano programiranje

Test MemoryDictionaryTest

@Test public void testRemove() { dictionary.remove("knjiga"); assertThat(dictionary.get("knjiga"), is(nullValue())); }

@Test public void testSize() { assertThat(dictionary.size(), is(2)); dictionary.add("stol", "table"); assertThat(dictionary.size(), is(3)); dictionary.remove("knjiga"); assertThat(dictionary.size(), is(2)); }}

Objektno orijentirano programiranje, FER 12/4/16

hr.fer.oop.testing.example3

26 / 34

Page 27: Objektno orijentirano programiranje

Zadatak za domaću zadaću 1

Zadatak je proširiti klasu MemoryDictionary iz prethodnog primjera da podržava više prijevoda jedne riječi

Novi razred neka se zove MultiWordMemoryDictionary Rješenje je dano u primjeru

Objektno orijentirano programiranje, FER 12/4/16

hr.fer.oop.testing.example4

27 / 34

Page 28: Objektno orijentirano programiranje

Razred CHFCalculator

public class CHFCalculator {

private final ExchangeRateProvider erp;

public CHFCalculator(ExchangeRateProvider erp) { this.erp = erp; }

public double chfToHrk(double amountOfChfs) { return amountOfChfs * erp.getRate("CHF", "HRK"); }

public double hrkToChf(double amountOfHrks) { return amountOfHrks * erp.getRate("HRK", "CHF"); }}

Ovaj razred koristi objekt ExchangeRateProvider koji dohvaća podatke o trenutnom tečaju s Interneta (sporo, tečaj nije deterministički)

Objektno orijentirano programiranje, FER 12/4/16

hr.fer.oop.testing.example5

28 / 34

Page 29: Objektno orijentirano programiranje

Test CHFCalculatorTest

public class CHFCalculatorTest { private CHFCalculator calculator;

@Before public void setUp() { calculator = new CHFCalculator(new ExchangeRateProvider("sSqBg-VaQrq-aBm4L")); } @Test public void testChfToHrk() { assertThat(calculator.chfToHrk(100), is(639.9271)); assertThat(calculator.chfToHrk(200), is(1279.8542)); assertThat(calculator.chfToHrk(500), is(3199.6355)); } @Test public void testHrkToChf() { assertThat(calculator.hrkToChf(100), is(15.626779)); assertThat(calculator.hrkToChf(200), is(31.253558)); assertThat(calculator.hrkToChf(500), is(78.133895));} }

Objektno orijentirano programiranje, FER 12/4/16

hr.fer.oop.testing.example5

29 / 34

Page 30: Objektno orijentirano programiranje

Imitiranje objekata

Testiranje malih jedinica kôda bi trebali raditi u izolaciji Minimiziramo utjecaj drugih jedinica kôda na rezultate testa

Komponentu možemo izolirati od drugih jedinica kôda koristeći imitiranje objekata (mocking)

Imitiranje objekata se koristi i u drugim slučajevima Rezultati su nedeterministički (ovise o vremenskom trenutku) Slijed događaja je neponovljiv (npr. redoslijed paketa u mreži) Operacije su prespore (npr. Dohvaćanje podataka s udaljenog poslužitelja) Ne postoji implementacija nekog objekta

Objektno orijentirano programiranje, FER 12/4/16 30 / 34

Page 31: Objektno orijentirano programiranje

Imitacija objekata u Javi

Postoji puno različitih okvira EasyMock Mockito PowerMock jMock JMockit

Slične funkcionalnosti, različita sintaksa Mi ćemo koristiti Mockito

Potrebno je skinuti datoteku mockito-all-1.9.5.jar s adrese https://mockito.googlecode.com/files/mockito-all-1.9.5.jar i dodati je kao vanjsku knjižnicu (novo: org.mockito:mockito-core:2.2.28)

Priručnik za Mockito se nalazi na sljedećoj adresi http://docs.mockito.googlecode.com/hg/1.9.5/org/mockito/Mockito.html

Objektno orijentirano programiranje, FER 12/4/16 31 / 34

Page 32: Objektno orijentirano programiranje

Izvođenje testa s imitacijom objekta

Test se sastoji od 4 faze1. Stvaranje imitiranog objekta

– Testirajući razred mora imati bilješku @RunWith(MockitoJUnitRunner.class)– Svaki imitirani objekt mora imati bilješku @Mock

2. Definiranje ponašanja imitiranog objekta tijekom testa (unutar metode s bilješkom @Test)

– when(mock.someMethod(methodParameters)).thenReturn(mockedResult)

– when(mock.someMethod(methodParameters)).thenThrow(new SomeException())

– when(mock.someMethod(methodParameters)).thenCallRealMethod()

3. Izvršavanje testa4. Provjeravanje broja pozivanja imitiranog objekta tijekom testa (unutar metode s

bilješkom @Test) jer imitirani objekt pamti broj pozivanja– verify(mock, times(expectedNo)).someMethod(methodParameters);– Umjesto times(), možemo koristiti i neku od sljedećih metoda verifikacije: never(),

atLeastOne(), atLeast(), atMost()

Objektno orijentirano programiranje, FER 12/4/16 32 / 34

Page 33: Objektno orijentirano programiranje

Test CHFCalculatorMockitoTest @RunWith(MockitoJUnitRunner.class)public class CHFCalculatorMockitoTest {

private CHFCalculator calculator;

@Mock ExchangeRateProvider mockErp;

@Before public void setUp() { calculator = new CHFCalculator(mockErp); } @Test public void testPrintRates() { calculator.printRates(); verify(mockErp).printRates(); }…

Objektno orijentirano programiranje, FER 12/4/16

hr.fer.oop.testing.example6

33 / 34

Page 34: Objektno orijentirano programiranje

Test CHFCalculatorMockitoTest …@Test public void testChfToHrk() { when(mockErp.getRate("CHF", "HRK")).thenReturn(6.399271); assertThat(calculator.chfToHrk(100), closeTo(639.9271, 0.0000001)); assertThat(calculator.chfToHrk(200), closeTo(1279.8542, 0.0000001)); assertThat(calculator.chfToHrk(500), closeTo(3199.6355, 0.0000001)); verify(mockErp, times(3)).getRate("CHF", "HRK"); }

@Test public void testHrkToChf() { when(mockErp.getRate("HRK", "CHF")).thenReturn(0.15626779); assertThat(calculator.hrkToChf(100), closeTo(15.626779, 0.0000001)); assertThat(calculator.hrkToChf(200), closeTo(31.253558, 0.0000001)); assertThat(calculator.hrkToChf(500), closeTo(78.133895, 0.0000001)); verify(mockErp, times(3)).getRate("HRK", "CHF"); } }

Objektno orijentirano programiranje, FER 12/4/16

hr.fer.oop.testing.example6

34 / 34

Page 35: Objektno orijentirano programiranje

Ponavljanje

Junit testovi (junit:junit:4.12, org.hamcrest:hamcrest-all:1.3)– Metode označene s @Test– @Before i @After: metode koje inicijaliziraju članske varijable

prije i uništavaju nakon poziva testnih metoda– @BeforeClass i @AfterClass: statičke metode koje

inicijaliziraju/uništavaju statičke varijable jednom, prije te nakon svih testnih metoda

import static paket.razred.*;

– Uključuje sve statičke metode u trenutni doseg pa ih se može izravno pozivati bez navođenja razreda (čitljiviji kod)

Objektno orijentirano programiranje, FER 12/4/16 35 / 34

Page 36: Objektno orijentirano programiranje

Ponavljanje

Assert.assertThat(obj, matcher)– Omogućava da se provjere delegiraju vanjskim strategijama

(Google: oblikovni obrazac Strategija; engl. Strategy)– Provjera je implementacija sučelja Matcher tj. razred izveden iz

org.hamcrest.BaseMatcher

– Razred org.hamcrest.CoreMatchers nudi niz metoda tvornica za stvaranje niza implementiranih strategija

– Razred org.hamcrest.Matchers ovo dopunjava još nekim metodama tvornicama

– Uz statički import omogućava pisanje čitljivijih testova

Objektno orijentirano programiranje, FER 12/4/16 36 / 34

Page 37: Objektno orijentirano programiranje

Ponavljanje

Mockito (org.mockito:mockito-core:2.2.28)– Omogućava stvaranje zamjenskih objekata

● Najprije ih treba podesiti: reći što se treba dogoditi kada se pozove neka njegova metoda

● Potom ga treba iskoristiti u testiranoj metodi● Potom treba provjeriti je li se dogodilo što smo očekivali

– Tri načina uporabe:● objekt = Mockito.mock(…)

● @Mock anotacija i MockitoAnnotations.initMocks(this);● @Mock anotacija i @RunWith(MockitoJunitRunner.class)

Objektno orijentirano programiranje, FER 12/4/16 37 / 34