Ddt dizajn vođen testiranjem final

65
UNIVERZITET U SARAJEVU Fakultet za saobraćaj i komunikacije Predmet: Informacioni sistemi u saobraćaju i komunikacijama - Design-driven testing (Dizajn vođen testiranjem) - - - -seminarski rad--- Mentor: Studenti: mr. Alem Čolaković, dipl.ing. Minela Hasanović, 6545 Predmetni nastavnik: Irma Hodžić, 6531 1

description

 

Transcript of Ddt dizajn vođen testiranjem final

Page 1: Ddt dizajn vođen testiranjem final

UNIVERZITET U SARAJEVU

Fakultet za saobraćaj i komunikacije

Predmet: Informacioni sistemi u saobraćaju i komunikacijama

- Design-driven testing (Dizajn vođen testiranjem) -

- - -seminarski rad---

Mentor: Studenti:

mr. Alem Čolaković, dipl.ing. Minela Hasanović, 6545

Predmetni nastavnik: Irma Hodžić, 6531

Doc.dr. Mugdim Bublin Merima Omerika, 6516

Anela Lavić, 6541

Lemana Korić, 6664

Amina Ćurovac, 6665

Sarajevo, novembar 2012.

SADRŽAJ

1

Page 2: Ddt dizajn vođen testiranjem final

Uvod 3

1. Dizaj vođen testiranjem u teoriji4

1.1. Različite vrste testiranja 5

1.2. Vođenje test slučajeva iz dijagrama robusnosti 9

1.3. Korištenje agilnog dodatka za ICONIX/EA 11

1.4. Vođenje test jedinica sa test slučajeva 13

1.5. Kratki uvod u JUnit 14

1.6. Pisanje efektivnih testova jedinica 17

2. Dizaj vođen testiranjem u praksi 18

2.1. Testovi jedinica za Internet knjižaru 18

2.2. Testiranje Prikaz Početne Stranice 20

2.3. Pokretanje testova iz test paketa 25

2.4. Testiranje Preuzmi Detalje Knjige Kontrolor 26

2.5. Testiranje Prikaži Detalje Knjige Kontrolor 32

2.6. Testiranje Prikaz Stranica Knjiga Nije Pronađena Kontrolor 40

3. Deset najvećih grešaka dizajna vođenog testiranjem 45

Zaključak 46

Bibliografija

Popis slika i tabela

UVOD

2

Page 3: Ddt dizajn vođen testiranjem final

Lahko je pogledati u programski modul, i reći „Eto, to je završeno“, ali osjećaj završetka može

biti varljiv. Kako možemo znati sigurno da je kod završio sve „use case“ (korištene slučajeve)

scenarije, a ne samo osnovne kurseve, već i alternativne takođe?

DDT (design-driven testing) – dizaj vođen testiranjem pruža neprobojnu metodu za proizvodnju

test slučajeva, kako bi verifikovali da su svi naznačeni scenariji završeni. Možemo takođe,

koristiti ovaj proces da napišemo izvršne testove iz testnih slučajeva.

Testiranje je proces koji bi trebao početi mnogo prije kodiranja. Počinjanje testiranja proizvoda

poslije nakon što je navodno „završen“ je marginalno bolji, ali bi testni proces trebao početi

mnogo prije nego što se uopće počne kodirati. Priprema za testiranje počinje u toku faze analize,

identifikovanjem testnih slučajeva uz korištenje robusnih dijagrama (robustness diagrams).

Ranim testiranjem, moguće je eliminirati mnogo više kvarova, prije nego što se uopće pojave.

Testiranje slijedi ubrzo nakon preliminarnog dizajna, a onda pisanje jedinica test kodova tokom

implementacije. Moramo biti sigurni da su testovi povezani zajedno za zahtjevima. Ne iz razloga

da svaki test bi trebao biti praćen unazad ka zahtjevima, ali bi trebao bar postojati test da

„dokaže“ da je svaki zahtjev proveden tačno. Proces koji ćemo opisati u ovom poglavlju je jedna

metoda za rađenje upravo toga: pokretanje testova jedinica iz korištenih slučajeva.

1. Dizaj vođen testiranjem u teoriji

3

Page 4: Ddt dizajn vođen testiranjem final

Počet ćemo ovo poglavlje osvrtanjem na pretpostavke i osnovne teorije DDT. Pokazat ćemo par

primjera kroz rad, koje ćemo kasnije prenijeti u podpoglavlje „Dizajn vođen testiranjem u

praksi“, ali svakako potrebno je da se prvobitno osvrnemo na teoriju. Principi koje ćemo

prodiskutovati u ovom poglavlju mogu biti sumirani u listu smjernica. Naša lista „top 10“ :

10. Usvojiti testiranje gdje se svaki pronalazak kvara prihvata kao pobjeda, a ne poraz. Ako

pronađemo ( i popravimo) kvar u testiranju, korisnici ga neće ponaći u konačnom proizvodu.

9. Razumijevanje različitih vrsta testiranja, kako i to kada se oni koriste. Upoznavanje sa

različitim vrstama testova koje ćemo opisati u ovom poglavlju i primjena svakog testa u pravo

vrijeme, a isto tako važno, korištenje isporuka koje kreiramo na putu za pripremu svakog testa u

unaprjeđenju.

8. Kada testiranje jedinica kreira jedan ili više testova za svaki kontroler na svakom robusnom

dijagramu, također kreira jedan ili više jediničnih testova za svaku operaciju na svakoj klasi sa

dizajnom.

7. Za realne sisteme, koristimo elemente dijagrama stanja kao osnovu za testove slučajeva.

Na primjer, test odgovara različitim elementima koji pokreću promjene stanja. Tokom ove vrste

testiranja, pratimo promjene u osobinama objekata kako bi testirali interakcije između objektnih

metoda. Možemo koristiti elemente dijagrama stanja kao bazu za testove slučajeva.

6. Uraditi provjeru nivoa zahtjeva , provjeravajući svaki zahtjev koji smo identificirali.

5. Koristiti matricu slijedivosti kao pomoć u provjeri zahtjeva.

4. Uraditi scenario nivoa pihvatljivosti za svaki korišteni slučaj.

3. Proširiti teme u testnim scenarijima za pokrivanje kompletnog puta, kroz odgovarajući dio

osnovnog kursa i dodanog kursa u testiranju scenarija.

2. Koristiti okvir testiranja kao što je JUnit, za pohranjivanje i oganizovanje testova jedinica.

1. Održavanje testova jedinica dobro preciziranim.

1.1. Različite vrste testiranja

4

Page 5: Ddt dizajn vođen testiranjem final

Treba li bi posmatrati testiranje kao skup interativnih i inkremantalnih razvojnih ciklusa, ne samo

kao nešto što se povremeno radi nakon što izdvojite hrpu kodova? Razlog za to je jednostavan:

test dokazuje da proizvod odgovara specificiranoj namjeni.

Testovi samo po sebi trebaju biti veoma čvrsto povezani sa zahtjevima, na mikroskopskom

nivou. Ako su testovi usko povezani sa zahtjevima, onda se prolaskom testa dokazuje da softver

odgovara svojoj specificiranoj namjeni, a ako testovi nisu povezani sa zahtjevima onda prolazak

testa, samim po sebi je beznačajan.

Ključ za testiranje je razumijevanje različitih vrsta testova, i posebno kada u ciklusu života

softvera, koja vrsta testa treba biti upotrijebljena. Slika 1. pokazuje koji testovi trebaju biti

izvedeni za svaku fazu u ICONIX Process-u.

Tako, za testove koji su preliminarno dizajnirani i provedeni zadovoljavavajuće sa

specifikacijama, provodimo integracione testove, pa nadalje. Pripreme za svaku vrstu testa

mogu početi dobro unaprijed. Na primjer, sve dok je poslovni ugovor (u suštini ugovor između

kompanije i kupca) nepotpisam, QA može početi špekulaciju izvedenih testova, baziranim na

sadržaju poslovnog slučaja. Slično, sve dok je korišteni slučaj napisan, softver testeri mogu

početi pisati testove za taj korišteni slučaj.

Mnogi od testova višeg nivoa mogu biti napisani u obliku testova jedinica. Na primjer, kao što

ćemo vidjeti kasnije u ovom radu, poželjno je da izvodimo testove jedinica i metode, direktno iz

kontrola u preliminarnom dizajnu, koji su u suprotnom, izvođeni od korištenih slučajeva.

5

Page 6: Ddt dizajn vođen testiranjem final

Slika 1. „V“ model softverskog testiranja primjenjljivog u ICONIX Procces-u

Tabela 1. opisuje različite vrste testova prikazane u slici 1.

6

Page 7: Ddt dizajn vođen testiranjem final

Test Kada (i zašto) bi trebali ih izvoditi

Test jedinicaTestiranje individualnih softverskih komponenti. Može se koristiti za simulaciju inputa i outputa komponente, tako da može raditi u samostalnom načinu

Testiranje jedinica počinje prije integracije.Testiranje jedinica se izvršava na svakoj izgradnji softvera, kroz razvojne faze ( uključujući fazu popravka kvarova, nakon što je softver pušten u testiranje sistema)

Integracioni testTestiranje se vrši da se otkriju greške u sučeljima i u interakciji između integrisanih komponenti.Za razliku od testova kompatibilnosti, klase su dio ukupnog sistema dizajna

Vrši se nakon testiranja jedinica

Test kompatibilnostiTestiranje da sistem sarađuje dobro sa ostalim „vanjskim“ sistemima, sa kojima se zahtjeva da komunicira.

Nije isti kao integracioni test, iako se oba rade u isto vrijeme

Test sistemaFunkcionalni i behioralni dizaj test slučaja. Selekcija test slučaja koja je bazirana na analizi specifikacija komponenti bez upućivanja na unutarnje djelovanje. Funkcionalno testiranje sastoji se od mnogih korištenih slučajeva i poslovnih procesa ispitivanja, ali uključuje i testiranje funkcionalnih zahtjeva.

Vrši se nakon integracionog testa.Test sistema, teži da bude fokusiran na razvoj. Njegova namjena je da dokaže da sistem koji je naznačen je i dostavljen

Test prihvatljivostiFormalno testiranje provedeno od strane kupca, da se utvrdi da li sistem zadovoljava zahtjeve naznačene u ugovoru

Test prihvatljivosti provodi se u istoj liniji sa testom sistema ali je isticanje drugačije. Iznosi se da bi se utvrdilo da sistem isporučuje ono što je stvarno traženo.

Beta testingProvodi se od strane krajnjeg korisnika koji nije drugačije uključen u razvoj.

Provodi se prije testa prihvatljivosti, u okruženju što bližem proizvodnom okruženju.

Test puštanjaProvjera da završeni proizvod precizno odražava poslovni slučaj

Radi se u tački u kojoj softver treba biti isporučen kupcu, da se osigura da je proizvod razvijen u skladu sa specifikacijama i da u potpunosti postiže ciljeve.

Tabela 1. Različite vrste testova i kada ih primjeniti

Kao dodatak navest ćemo neke vrste testova koje prolaze kroz razvojni proces ili nisu bazirane

na specifičnoj isporuci (Tabela 2.).

7

Page 8: Ddt dizajn vođen testiranjem final

Test Kada (i zašto) bi trebali ih izvoditi

Nefunkcionalni test zahtjeva

Testiranje onih zahtjeva koji nisu vezani za

funkcionalnost (izvođenje, korisnost,...)

Ovaj test treba se provoditi kroz životni ciklus

softvera, gdje je god moguće ( čak i na nivou

testa jedinica).

Test izvodljivosti

Testiranja provedena za procjenu popustljivosti

sistema ili komponenti sa specificiranim

zahtjevima izvođenja.

Ovaj test može ( i treba) biti izveden u svakoj

prilici ali se uglavnom izvršava nakon testa

sistema.

Test regresije

Retestiranje prethodno testiranog programa

slijedeći modifikacije da osigura da neuspjesi

nisu uvedeni ili neotkriveni kao rezultat

napravljene promjene.

Ovo testiranje se izvršava nakon što kod bude

pušten u test sistema. Test jedinica je forma

regresijskog testa ako se izvede pravilno.

Test otpornosti na stres

Testiranja provedena za evaluaciju sistema ili

komponente na granici ili izvan svojih granica,

specificiranih zahtjevima.

Ovaj test se izvodi nakon testa izvodljivosti.

Test zapremine

Ispitivanje gdje je sistem podvrgnut velikim

količinama podataka.

Izvodi se nakon testa sistema.

Tabela 2. Testovi koji prolaze kroz razvojni proces

1.2. Vođenje test slučajeva iz dijagrama robusnosti

8

Page 9: Ddt dizajn vođen testiranjem final

Sa ICONIX Procces-om, ulažemo trud kako bi napisali korištene slučajeve, i identifikujemo

objekte koji sudjeluju u korištenom slučaju kao i funkcije koje ti objekti obavljaju na dijagramu

robusnosti (funkcije su prikazane kao kontroleri). Pošto smo uložili trud u identifikaciju logičnih

softverskih funkcija, bilo bi dobro kada bismo dobili paket test slučajeva koji nas podsjećaju da

testiramo sve funkcionalnosti korištenog slučaja. Slika 2. prikazuje pregled DDT, u kojoj test

slučajevi su kreirani direktno od kontrolera na dijagramu robusnosti.

Kako slika 2. prikazuje, možemo automatski transformisati dijagram robusnosti u sekvencijalni i

dijagram test slučajeva korišteći jednostavnu skriptu. Test kod može biti naknadno generiran za

test jedinica okvira kao što su JUnit or NUnit.

Sada ćemo to detaljnije objasniti kroz korake na primjeru. Kada definiramo logične funkcije sa

kontrolorima korištenih slučajeva, potrebno je te funkcije testirati. Radom sa dijagramom

robusnosti, možemo kreirati dijagram test slučaja, koji prikazuje test slučaja za svakog

kontrolora. To ćemo uraditi tako što ćemo kopirati sve kontrolore sa dijagrama robusnosti na

novi dijagram, i onda povezati sa testom slučaja korištenjem <<realize>> konektora. To ćemo

ubrzo prikazati i na primjeru.

9

Page 10: Ddt dizajn vođen testiranjem final

Slika 2. Pregled DDT-a

Svaki test slučaja sadrži više scenarija. Da bi identifikovali test scenario za svaki kontrolor/test

slučaj, trebamo slijediti slijedeće korake:

1.Ponovo pročitati tekst korištenog slučaja da se podsjetimo sadržaja u kojem je kontroler

korišten

2. Za svaki test slučaj, kreirati test scenario za svaki korišteni scenario (osnovni i alternativni

kursevi)

10

Page 11: Ddt dizajn vođen testiranjem final

3. Imenovati svaki test scenario nakon orginalnog korištenog scenarija. Na primjer, za kontroler

“Preuzeti detalje knjige”( Retrieve Book Details), alternativni scenario nazvan “Knjiga nije

pronađena” (Book Not Found), će dovesti do test scenarija “Knjiga nije pronađena” u test slučaju

nazvanim “Preuzeti detalji knjige”.

1.3. Korištenje agilnog dodatka za ICONIX/EA

Trebamo naglasiti da ICONIX Process radi jednako dobro sa bilo kojim objektno-orjentiranim

programskim jezikom, CASE alatom itd. Enterprise Arhitect (EA) ima poseban dodatak koji

automatizira mnogo “prijelaznog” posla kada premještamo između dijagrama u ICONIX

Process-u. Na primjer, dodatak će automatski kreirati set robusnih dijagrama za dijagram

korištenog slučaja (slika 3. ), i dodatak će popuniti sekvencijalni dijagram koristeći granice,

entitet i kontroler objekte na robusnom dijagramu, što je veoma velika ušteda na vremenu.

Slika 3. Korištenje Agilnog ICONIX/EA dodatka za generiranje dijagrama

11

Page 12: Ddt dizajn vođen testiranjem final

Slika 4. Generacija test slučajeva u EA

Za potrebe testiranja, dodatak automatski kreira dijagram test slučaja od kontrolora na robusnom

dijagramu (slika 4.). Onda je moguće napisati izvršni test jedinica za svaki test slučaj.

Primjećujemo da je svaki test slučaja povezan sa kontrolorom. Drugim riječima, postoji jedan

test slučaj po kontroloru. Veza između test slučaja i kontrolera je “realizes” (ostvaruje), ista veza

koja je korištena da pokaže klase implementacije/realizacije sučelja.

Desnim klikom na svaki test slučaj možete dodavati individualne scenarije.(slika 5.)

12

Page 13: Ddt dizajn vođen testiranjem final

Slika 5. Dodavanje test scenarija u EA

1.4. Vođenje test jedinica sa test slučajeva

Da podsjetimo, moramo modelirati test slučaj na kontrolora iz svog robusnog dijagrama-da svaki

kontroler dobija tačno jedan test slučaj, i za svaki test slučaj, kreirati jedan ili više test scenarija.

Jednom kada kreiramo test slučaj i alociramo test scenarijo na svaki, vrijeme je da kreiramo

kostur test jedinica.

13

Page 14: Ddt dizajn vođen testiranjem final

Uputstva za vođenje test jedinica iz test slučajeva:

Za svaki test slučaj, kreiramo jednu klasu test jedinica. Na primjer, ako se test slučaja

zove “Test Preuzimanja Detalja Knjige”, onda kreirate klasu JUnit testa nazvanu

TestPreuzimanjaDetaljaKnjige.

Za svaki test scenario, kreiramo jednu testnu metodu u klasi testova jedinica. Na primjer,

ako je test slučaj nazvan Knjiga Nije Pronađena, kreiramo test metodu nazvanu

testKnjigaNijePronađena().

Napisati test jedinica sa ugla posmatranja objekta, tj kontrolora.

Ako otkrijemo nove alternativne tečaje dok razmišljamo o scenariju test slučaja, što je

moguće, ne treba oklijevati da ih dodamo u korišteni slučaj.

Proći ćemo kroz neke primjere kreiranja testova jedinica iz testova slučajeva.

1.5. Kratki uvod u JUnit

Za kodiranje primjera kasnije u ovom poglavlju koristit ćemo JUnit, popularnu Java-baziranu

okvirnu test jedinicu. JUnit dio je xUnit porodice koja uključuje cppUnit za C++, n Unit za

C#/.NET i DUnit za Borlan Delphi. Iako se izvorni kod može razlikovati ovisno o

jeziku/implementaciji, principi razmatrani u ovom poglavlju su u osnovi isti, bez obzira koji

okvir test jedinica koristimo.

Sa JUnit, pišemo test slučaj gdje svaki test slučaj je pojedinačna Java klasa. Unutar ove klase,

pojedinačne metode ispitivanja slijedite konvenciji imenovanja testa XYZ, gdje XYZ je ime

našeg testa. Ova konvencija imenovanja dozvoljava JUnit da automatski otkrije i pokrene test

metode, bez njihovog “proglašavanja” (npr. u vanjskom XML fajlu). Korištenje JUnit 4.0, test

metode može također biti identifikovano korištenjem Java 5 tvrdnji.

Unutar test metode, možete napisati Java kod koji poziva metode u klasama da budu testirane i

tvrdi da je rezultat upravo ono što se i očekivalo. Za dio tvrdnji , JUnit pruža broj različitih

metoda tvrdnji(npr., tvrditi da je vrijednost istinita, ili da vrijednost nije-nula, ili da dvije

vrijednosti su jednake). Test klasa može sadržavati bilo koji broj test metoda, iako je generalno

dobra ideja držati broj ispod pet. Slično, dobro je ograničiti svaku test metodu na jednu tvrdnju.

14

Page 15: Ddt dizajn vođen testiranjem final

Ovo čuva test scenarij fokusiranim na testiranje jedne stvari. Ako imamo potrebu da dodamo

više od jedne tvrdnje, vjerovatno tražimo više od jednog test scenarija stisnute u jednu test

metodu, tako da ne treba oklijevati da ih podijelimo.

Imamo primjer klase testa jedinica:

package test.com.iconixsw.bookstore.web;

import junit.framework.*;

public class AddToShoppingCartTest extends TestCase {

public AddToShoppingCartTest (String testName) {

super(testName);

}

public void testShoppingCartEmpty() throws Exception {

ShoppingCart cart = new ShoppingCart();

assertEquals("Cart should be empty", 0, cart.getNumItems());

}

public void testItemAdded() throws Exception {

ShoppingCart cart = new ShoppingCart();

LineItem item = new LineItem();

cart.addItem(item);

assertEquals("Cart should contain 1 item",

1, cart.getNumItems());

}

}

Test slučaj DodajUKorpuKupovineTest sadrži dvije test metode. Prva metoda je brza, razumna

provjera da se uvjerimo da ako je nova KorpaKupovine kreirana, počinje prazna.

15

Page 16: Ddt dizajn vođen testiranjem final

Druga test metoda provjerava da ako je jedan artikal dodan u korpu, onda korpa sadrži tačno

jedan artikal. U oba slučaja koristimo asserEquals(), koji ima tri argumenta:

• Koristan opis koji se pojavi ako test ne izvrši uslove

• Vijednost koja predstavlja kakva očekivana vrijednost treba biti

• Rezultat testiranog koda, koji bi naravno, riješio samu vrijednost drugog argument.

Obje test metode postavljaju objekat KorpaKupovine. Zapravo, uzeći u obzir da je test slučaj sve

o dodavanju artikla u KorpaKupovine, imalo bi smisla za oba testa da koriste istu postavku koda.

Srećom, JUnit omogućava a setUp() metodu samo za ovu namjenu. Da demonstriramo ovo,

pokazat ćemo novu verziju DodajUKupovnuKorpuTest, koji koristi setup() da eliminiše duple

kodove. Novi kod je prikazan u crvenoj boji:

package test.com.iconixsw.bookstore.web;

import junit.framework.*;

public class AddToShoppingCartTest extends TestCase {

private ShoppingCart cart;

public AddToShoppingCartTest (String testName) {

super(testName);

}

public void setUp() {

cart = new ShoppingCart();

}

public void testShoppingCartEmpty() throws Exception {

assertEquals("Cart should be empty", 0, cart.getNumItems());

}

public void testItemAdded() throws Exception {

LineItem item = new LineItem();

cart.addItem(item);

16

Page 17: Ddt dizajn vođen testiranjem final

assertEquals("Cart should contain 1 item",

1, cart.getNumItems());

}

}

SetUp() metoda se pokreće automatski, odmah prije početka svake test metode. Vrijedno je istaći

tačku da se ne pokreće samo jednom za cijeli test slučaj. Umjesto toga, pokreće se jednom za

svaku posebnu test metodu, tako da za svaku test metodu, garantiramo, dobar, svjež primjer

KupovneKorpe. Postoji takođe teardown() metoda koja radi obrnuto od setup() i korisna je za

zatvaranje vanjskih izvora kao što su veze baza podataka ili inpu/output tokovi. TearDown() se

pokreće odmah nakon svake pojedinačne metode.

Kroz veći dio ostatka ovog rada, proći ćemo kroz primjere da pokažemo kako pokretati testove

jedinica direktno i test slučajeva, koji su pokretani od strane kontrolora sa robusnih dijagrama a

koji su pokretani sa korištenih slučajeva. Naš cilj je da pružimo detaljno razumijevanje kako da

povežemo te testove zajedno sa zahtjevima na mikroskopskom nivou.

1.6. Pisanje efektivnih testova jedinica

Prije nego počnemo na primjeru, vrijedno je istaći neke najbolje prakse za pisanje dobrih testova

jedinica. Cijela knjiga je posvećena testovima jedinica, ali tehnike efektivnih testova jedinica sa

perspective dizajnom-vođenog testiranja mogu se sažeti veoma jezgrovito:

• Čuvanje testova jedinica precizno. Generalno, trebamo pokriti jedan test slučaj jednom

klasom testova jedinica i različitom permutacijom ili tvrdnjom test slučaja u svakoj test

metodi.

• Uvjeriti se da svaka test metoda testira tačno jednu stvar.

• Povezati testove jedinica sa klasama i metodama koju testiramo.

• Povezati testove jedinica sa objektima u preliminarnom dizajnu.

• Podjednako tretiranje koda test jedinica sa istim poštovanjem kao sa proizvodnim kodom.

17

Page 18: Ddt dizajn vođen testiranjem final

• Izbjegavanje duplikata u testu.

• Uvjeriti se da se testovi izvode 100% uspješno.

• Koristiti mock objects(lažne predmete), ali se ne oslanjati previše na njih.

U slijedećem poglavlju proći ćemo kroz primjer Internet knjižare, sve od dijagrama robusnosti,

do JUnit testova.

2. Dizaj vođen testiranjem u praksi

U ovom dijelu, ilustrirat ćemo teoriju iz prvog dijela ovog poglavlja, korištenjem projekta

Internet knjižare. Podsjetili smo se na detaljni dizaj iz 9 poglavlja i ovaj put, bez direktnog

prelaska na kodiranje, prvo testiramo neke test slučajeve direktno is robusnih dijagrama, i

spajamo ih sa detaljnim dizajnom. Onda koristimo test slučajeve da potvrdimo da:

• detaljni dizajn se poklapa sa korištenim slučajem

• kod se poklapa sa detaljnim dizajnom i čini ono za šta je namijenjen

2.1. Testovi jedinica za Internet knjižaru

Da napišemo test jedinica za Internet knjižaru, uzet ćemo kontrolore sa robusnih dijagrama za

korištene slučajeve Prikaži Detalje Knjige (Show Book Details) i Napiši korisničku recenziju

(Write Customer Review), proizvesti test slučajeve za njih i onda napisati test jedinica baziran na

test slučajevima. Ovaj korak bi trebali uraditi prioritetno za pisanje koda, tako da kada kodiramo,

imamo dovoljan set testova jedinica da sastavimo i testiramo ponovo. Slika 6. prikazuje dijagram

test slučaja. Ovaj dijagram je proizveden sa robusnog dijagrama za Prikaži Detalje Knjige.

18

Page 19: Ddt dizajn vođen testiranjem final

Slika 6. Generirani test slučaj za prikaži detalje knjige korišteni slučaj

Prikaži Stranicu Knjiga Nije Pronađena i test slučaj su prikazani crvenom bojom jer se radi o

alternativnim kursevima.

Da podsjetimo, svaki kontroler sa robusnog dijagrama dobija svoj test slučaj, i u svakom test

slučaju smo kreirali jedan ili više test scenarija. Za svaki test slučaj, kreiramo klasu testova

jedinica i za svaki test scenario kreiramo metodu test jedinica. Proći ćemo kroz ovaj process

jednom za svaki test slučaj (prikazan u slici 6.)

19

Page 20: Ddt dizajn vođen testiranjem final

2.2. Testiranje Prikaz Početne Stranice

U ovom dijelu, kreirat ćemo test scenario za Kontrolora Prikaz Početne Stranice,

najjednostavnijeg u grupi, i onda ćemo napisati JUnit test klasu.

Slijedi dio teksta korištenog slučaja koji je vezan za ovog kontrolora:

Kupac upiše u URL adresu za internet knjižaru početnu stranicu. Sistem prikaže listu knjiga iz

kataloga na početnoj stranici u obliku linkova koje možete otvoriti.

Test slučaj za ovog kontrolora je jednostavan, zapravo, trebamo samo jedan test scenario za ovaj

test slučaj zato što postoji malo toga što može krenuti “naopako”. Da dodamo test scenario u EA,

dvoklik na test slučaj i onda u prozorčiću Postavke kliknemo Scenario tab.(slika 7.) Postoji

samo jedan test scenario za ovaj test slučaj, tako da možemo očekivati da vidimo jednu test

metodu u klasi testa jedinica.

Slika 7. Dodavanje test scenarija za test slučaj Prikaz početne stranice

20

Page 21: Ddt dizajn vođen testiranjem final

Slijedi kostur JUnit testa za ovaj test slučaj:

package test.com.iconixsw.bookstore.web;

import junit.framework.*;

public class DisplayHomePageTest extends TestCase {

public DisplayHomePageTest(String testName) {

super(testName);

}

public void testDisplayHomePage() throws Exception {

}

}

Test proširuje TestSlučaj, klase JUnit. U JUnit, bilo koja metoda čije ime počinje sa test, je

automatski prepoznata kao test metoda, tako da u ovom slučaju imamo samo jednu test metodu,

testPrikazPočetneSTranice() koja je izvedena iz test scenarija prikazanog na slici 7. Ako test

slučaj ima na primjer tri test scenarija, onda ćemo vidjeti tri test metode umjesto samo jedne.

Slika 8 prikazuje izvedeni sekvencijalni dijagram PrikazDetaljaKnjige koji je vezan za ovaj test

slučaj.

Slika 8. Izvod iz sekvencijalnog dijagrama Prikaži početnu stranicu

21

Page 22: Ddt dizajn vođen testiranjem final

U ovom slučaju PočetnaKontroler se testira, i predmet poziva granični objekt, DispečerServlet.

Test jedinica mora potvrditi da rezultati sa nosiocZahtjeva() je ono što očekujemo, s obzirom da

se vrijednosti prenose. Metoda je:

public void testDisplayHomePage() throws Exception {

HomeController homeController = new HomeController();

ModelAndView modelAndView =

homeController.handleRequest(null, null);

assertEquals("Should be viewing home.jsp",

"home",

modelAndView.getViewName());

}

Sada kada imamo test, dobro je vježbati i pokušati učiniti ga neuspješnim, to će dokazati da će

raditi kada nastupi i stvarni neuspjeh u budućnosti. Možemo to uraditi pisajući praznu

nosiocZahtjeva() metodu:

package com.iconixsw.bookstore.web;

// import . . .

public class HomeController implements Controller {

public ModelAndView handleRequest(

HttpServletRequest request,

HttpServletResponse response)

throws ServletException, IOException {

22

Page 23: Ddt dizajn vođen testiranjem final

return new ModelAndView("");

}

}

Ova verzija PočetnaKontroler, vraća prazno ime. Ako pokrenemo ponovo test jedinica dobit

ćemo slijedeće:

____________________________________________________________________________

.F

Time: 0.015

There was 1 failure:

1) testDisplayHomePage

(test.com.iconixsw.bookstore.web.DisplayHomePageTest)

junit.framework.ComparisonFailure:

Should be viewing home.jsp. expected:<home> but was:<>

at test.com.iconixsw.bookstore.web.

DisplayHomePageTest.testDisplayHomePage

(DisplayHomePageTest.java:17)

FAILURES!!!

Tests run: 1, Failures: 1, Errors: 0

______________________________________________________________________

23

Page 24: Ddt dizajn vođen testiranjem final

To pokazuje da test mehanizam radi, pa možemo implementirati nosiocZahtjeva “pravilno”:

public ModelAndView handleRequest(

HttpServletRequest request,

HttpServletResponse response)

throws ServletException, IOException {

return new ModelAndView("home");

}

Pokretanjem testa trebali bi dobiti slijedeće :

_____________________________________________________________________________

.

Time: 0.016

OK (1 test)

______________________________________________________________________

U test metodi loše kreiranje je stvaranje resursa koji bi trebali biti kreirani u setup() metodi koja

se poziva prije svake test metode. Refaktorisani kod sada izgleda ovako:

package test.com.iconixsw.bookstore.web;

// import statements omitted

public class DisplayHomePageTest extends TestCase {

private HomeController homeController;

public DisplayHomePageTest(String testName) {

super(testName);

}

public void setUp() throws Exception {

24

Page 25: Ddt dizajn vođen testiranjem final

homeController = new HomeController();

}

public void tearDown() throws Exception {

homeController = null;

}

public void testDisplayHomePage() throws Exception {

ModelAndView modelAndView = homeController. handleRequest

(null, null);

assertEquals("Should be viewing home.jsp.",

"home",

modelAndView.getViewName());

}

}

Preokrenuli smo početnaKontroler u privatnu varijablu i premjestili kod koji kreira u setUp()

metodu. Takođe smo dodali teardown() metodu da podesimo početnaKontrolor nazad na

početak. Ovo nije neophodno ali je dobro radi uštede radne memorije u budućnosti. Povratak na

test pokazuje da ni jedna tvrdnja nije netačna. Proći ćemo kroz isti process za ostale kontrolore

prikazane u korištenom slučaju Prikaži Detalje knjige.

2.3. Pokretanje testova iz test paketa

Nismo još uvijek pokazali kako da pokrenemo sve testove iz jednog pokušaja. To je jednostavno

s JUnit-om. Moguće je grupirati sve klase testova jedinica zajedno u samo jedan test paket, i

pokrenuti ga:

package test.com.iconixsw.bookstore;

import test.com.iconixsw.bookstore.web.*;

import junit.framework.*;

25

Page 26: Ddt dizajn vođen testiranjem final

public class BookstoreTestSuite {

public static Test suite() {

TestSuite suite = new TestSuite();

suite.addTestSuite(DisplayHomePageTest.class);

// add more tests here . . .

return suite;

}

public static void main(String[] args) {

junit.textui.TestRunner.run(suite());

}

}

Ako pokrenemo InternetKnjižaraTestPaket iz komande, glavna metoda bit će nazvana paket(),

koji će skupiti sve individualne test slučajeve zajedno, i vratiti ih zajedno u jedan predmet. Ovo

će onda biti prebačeno u JUnit TestPokretač, koji proizvodi “OK” i “Neuspjeh” (“failures”) tekst

rezultate koje ćemo vidjeti u primjeru.

Kako pišemo više test klasa, dodajemo ih u test paket da bi se onda mogle pokrenuti zajedno.

Ako se testovi izvode dovoljno brzo, to znači da možemo pokrenuti sve testove svaki put kada

promijenimo nešto ili dodamo nešto novo.

2.4. Testiranje Preuzmi Detalje Knjige Kontroler (Retrieve Book Details

Controller)

U ovom dijelu, kreiramo test scenario za Preuzmi Detalje Knjige Kontroler, i onda pišemo i

pokrećemo njegovu JUnit test klasu. Ako spojimo Preuzmi Detalje Knjige Kontroler sa

slijedećim tekstom:

Kupac odabere link na početnoj stranici i sistem preuzme detalje knjige od odabrane knjige

26

Page 27: Ddt dizajn vođen testiranjem final

onda ovo sugerira da bi test trebao potvrditi da su knjige preuzete tačno iz baze podataka.

Da dodamo test slučaj u EA, dvoklikom otvorimo prozorčić Postavke i odaberemo Scenario tab.

Onda možemo dodati osnovni i alternativni scenario u test slučaj. Slika 9 prikazuje dva test

scenarija koja smo dodali za Preuzmi Detalje Knjige kontrolor/test slučaj.

Slika 9. Test scenario za Preuzmi detalje Knjige

Sada kada smo dodali test scenario potrebno je nadograđivanje korištenog slučaja, robusni

dijagram kako bi nacrtali sekvencijalni dijagram. Slijedeća etapa je kreiranje kostura testa

jedinica za ovaj test slučaj, korištenjem scenarija koji smo dodali. Sada ćemo pokazati kostur test

27

Page 28: Ddt dizajn vođen testiranjem final

scenarija za Preuzmi Detalje Knjige kontroler/test slučaj. Stvarna test metoda (izvedena iz

scenarija test slučaja) prikazana je crvenom bojom:

package test.com.iconixsw.bookstore.dao;

import junit.framework.*;

/**

* Test case for the Retrieve Book Details controller.

*/

public class RetrieveBookDetailsTest extends TestCase {

public RetrieveBookDetailsTest(String testName) {

super(testName);

}

public void setUp() throws Exception {

}

public void tearDown() throws Exception {

}

public void testBookIdFound() {

}

public void testBookIdNotFound() {

}

}

Metode testIdKnjigaPronađena() (testBookIdFound()) i testIdKnjigaNijePronađena()

(testBookIdNotFound()) su izvedene direktno iz dva scenarija prikazana na slici 9. Kao što smo

ranije rekli, želimo da testiramo ID Knjiga pronađena (ili nije pronađena) direktno iz baze

podataka. Zlatno pravilo za testove jedinica je to da oni trebaju imati mogućnost brzog

pokretanja. Ako testovi jedinica se ne pokreću brzo, onda se programeri neće uopšte truditi da ih

28

Page 29: Ddt dizajn vođen testiranjem final

pokreću tokom programiranja. Iz ovog razloga, dobra je praksa pokušati izbjeći pisanje testova

koji ostvaruju vezu sa vanjskim izvorima (npr. baza podataka). Povezivanje sa bazom podataka

(čak i lokalnom) i pokretanje upita ili nadogradnji može učiniti testove jedinica da se pokreću

neproporcionalno sporo, posebno kada je ista postavka ili kod ponovljen više od stotinu puta.

Ali, ako ne možemo uključiti kod baze podataka u brzi test, kako da zapravo testiramo bilo šta?

Jedan odgovor je da koristimo tzv. mock objekte (lažne). Na primjer, možemo zamijeniti naš

JDBC specifične DAO klase sa “lažnom” verzijom, čija je osnovna misija da osigura iste

podatke test jedinica, iznova i iznova, čak veoma brzo.

Dodat ćemo neke kodove u testnu klasu da preuzmemo ID Knjige i da potvrdimo da je primljen:

private BookDao bookDao;

public void testBookIdFound() {

Book book = bookDao.findById(1);

assertNotNull("ID 1 should be found", book);

}

Ako pokušamo da pokrenemo test jedinica sada, dobit ćemo NullPointerException, zbog toga što

BookDao (knjiga osigurana) nije učitan:

public void setUp() throws Exception {

bookDao = new MockBookDao();

}

Očito se ovo neće sastaviti iz razloga što ne postoji MockBookDao, i sada je dobro vrijeme da ga

ubacimo:

package com.iconixsw.bookstore.dao.mock;

// import statements omitted . . .

public class MockBookDao implements BookDao {

29

Page 30: Ddt dizajn vođen testiranjem final

private HashMap booksById;

public MockBookDao() {

initData();

}

public List findAll() throws DataAccessException {

return (List) booksById.values();

}

public Book findById(int bookId) throws DataAccessException {

return (Book) booksById.get(new Integer(bookId));

}

private void initData() {

Book favWidgets = new Book();

favWidgets.setId(1);

favWidgets.setTitle("My Favorite Widgets");

Book uncommon = new Book();

uncommon.setId(2);

uncommon.setTitle("The Uncommon Event");

booksById = new HashMap();

booksById.put(new Integer(1), favWidgets);

booksById.put(new Integer(2), uncommon);

}

}

30

Page 31: Ddt dizajn vođen testiranjem final

BookDao čini najjedonostavniju moguću stvar, a to je kreiranje par objekata Knjiga i stavljanje

tih objekata u HashMap, ključem po ID knjige. Podaci se nikada ne spašavaju na vanjski disk

već u internoj memoriji.

Sada kada imamo sastavljen test, trebali bi ga pokrenuti kroz JUnit, ali bi prvobitno trebali

vidjeti neuspjeh testa kako bi potvrdili da test radi. Da bi to uradili samo ćemo kratko promijeniti

initData() metodu na slijedeći način:

Book favWidgets = new Book();

favWidgets.setId(5);

favWidgets.setTitle("My Favorite Widgets");

Jednostavno smo promjenili 1 u 5 tako da lažni DAO ne vrati knjigu sa ID oznakom 1.

Pokretanje testa sada će donijeti slijedeće rezultate:

_____________________________________________________________________________

.F

Time: 0

There was 1 failure:

1) testBookIdFound

(test.com.iconixsw.bookstore.dao.RetrieveBookDetailsTest)

junit.framework.AssertionFailedError:

ID 1 should be found

at test.com.iconixsw.bookstore.dao.

RetrieveBookDetailsTest.

testBookIdFound(RetrieveBookDetailsTest.java:29)

FAILURES!!!

Tests run: 1, Failures: 1, Errors: 0

____________________________________________________________________

31

Page 32: Ddt dizajn vođen testiranjem final

Na ovaj način možemo se uvjeriti da će test raditi ispravno kada dođe do stvarnog neuspjeha

testa. Sada kada vratimo vrijednost ponovo 1 i uradimo ponovo test dobit ćemo slijedeće

rezultate:

______________________________________________________________________________

.

Time: 0

OK (1 test)

______________________________________________________________________

Trenutno testiramo samo jedan način, odnosno Knjiga pronađena, trebamo to uraditi i za

KnjigaNijePronađena:

public void testBookIdNotFound() {

Book book = bookDao.findById(-1);

assertNull("ID -1 should not be found", book);

}

2.5. Testiranje Prikaži Detalje Knjige Kontrolor

Tekst u korištenom slučaju povezan za ovaj test slučaj je:

… sistem preuzima detalje knjige za izabranu knjigu i prikazuje ih na Pogledaj Detalje Knjige

stranici….

Slika 10 prikazuje test scenario koji je dodat u EA za ovaj test slučaj.

32

Page 33: Ddt dizajn vođen testiranjem final

Slika 10. Test scenario za Prikaži Detalje knjige kontrolor/test slučaj

Tu su tri scenarija: “Stranica prikazana”, “Detalji knjige pronađeni” i “Detalji knjige nisu

pronađeni”… Jedan od ovih scenarija nije u redu. Vraćanjem u test slučaj prikazan u slici 6,

uviđamo da tamo već postoji podjeljen alternativni test za test slučaj gdje detalji knjige nisu

pronađeni.

Tako za ovaj test slučaj, zapravo postoje dva test scenarija: “Prikazana stanica” i “Detalji knjige

pronađeni”. Oba ova su osnovni test scenario, što ima smisla, zato što test slučaj sam po sebi, je

za jednog kontrolora u osnovnom slučaju korištenog slučaja. Slika 11. prikazuje izvod iz

sekvencijalnog dijagrama Prikaži Detalje Knjige.

33

Page 34: Ddt dizajn vođen testiranjem final

Slika 11. Izvod iz sekvencijalnog dijagrama Prikaži Detalje Knjige

Zapamtimo da trebamo pisati test sa tačke gledišta objekta zvanog kontrolor. Pozivajući objekt je

uglavnom granični objekt, iako može takođe biti i drugi kontrolor. Želimo da pozivi idu u

kontrolor koji se testira. Kao što možemo vidjeti u slici 11, to znači testiranje dvije metode:

rukovati() (handle()) i provjeriKnjigaPronađena() (checkBookFound()).

Slijedi kostur test klase za Prikaži Detalje Knjige kontrolor/test slučaj (test metode su prikazane

crvenom bojom):

package test.com.iconixsw.bookstore.web;

import junit.framework.*;

/**

* Test case for the Display Book Details Page controller.

*/

public class DisplayBookDetailsPageTest extends TestCase {

public DisplayBookDetailsPageTest(String testName) {

34

Page 35: Ddt dizajn vođen testiranjem final

super(testName);

}

public void setUp() throws Exception {

}

public void tearDown() throws Exception {

}

public void testPageDisplayed()throws Exception {

}

public void testBookDetailsFound()throws Exception {

}

}

Provjeravanjem slike 11, željet ćemo da kreiramo DetaljiKnjigeKontrolor objekat da poguramo i

podstaknemo, i imalo bi smisla da to stavimo u setup() tako da isti osnovni kod bude podijeljen

od strane obje test metode:

public void setUp() throws Exception {

bookDetailsController = new BookDetailsController();

bookDetailsController.setBookDao(new MockBookDao());

}

private BookDetailsController bookDetailsController;

U setUp(), sada kreiramo novi DetaljiKnjigeKontrolor:

public void setBookDao(BookDao bookDao) {

this.bookDao = bookDao;

}

private BookDao bookDao;

35

Page 36: Ddt dizajn vođen testiranjem final

Naredni kod pokazuje početak prve metode:

testPageDisplayed():

public void testPageDisplayed() throws Exception {

Book command = new Book();

command.setId(1);

ModelAndView modelAndView =

bookDetailsController.handle(null, null, command, null);

// assert...

}

Sada možemo dodati handle()-rukovati metodu u DetaljiKnjigeKontrolor:

protected ModelAndView handle(

HttpServletRequest request,

HttpServletResponse response,

Object command,

BindException errors) throws Exception {

return null;

}

U početku to nas vraća nuli, zato što želimo da budemo u mogućnosti da prvo pokrenemo test i

vidimo neuspjeh. Nazvat ćemo metodu “test” tako da kasnije znamo da je za test jedinica:

public ModelAndView testHandle(Book command)

throws Exception {

return handle(null, null, command, null);

}

36

Page 37: Ddt dizajn vođen testiranjem final

Jedini parametar koji je zapravo važan je Knjiga. Sada možemo ponovo napisati test metodu za

korištenje ove nove metode:

ModelAndView modelAndView =

bookDetailsController.testHandle(command);

Provjerom sekvencijalnog dijagrama u slici 11., vidimo da druga metoda

provjeraKnjigaPronađena(), je zapravo privatna metoda nazvana rukovati() (Handle()) tako da ne

trebamo pisati specifičnu metodu za to. Umjesto toga, izlaz iz provjeraKnjigaPronađena() će

doprinijeti eventualnim izlazima iz rukovanje(), koji trebamo testirati. Sada možemo sastaviti

ostatak, i očekivati neuspjeh.

Slijedeći korak je da napišemo stvarni kod za rukovanje() metodu, osim ako nismo dodali neku

tvrdnju u dvije metode još uvijek, tako da trenutno ne testiramo ništa. To je veliki skup kodova

sa mnogo duplikata, koje ćemo kasnije pretvoriti u nešto kompaktnije.

public class DisplayBookDetailsPageTest extends TestCase {

public DisplayBookDetailsPageTest(String testName) {

super(testName);

}

public void setUp() throws Exception {

bookDetailsController = new BookDetailsController();

bookDetailsController.setBookDao(new MockBookDao());

}

private BookDetailsController bookDetailsController;

public void tearDown() throws Exception {

bookDetailsController = null;

}

37

Page 38: Ddt dizajn vođen testiranjem final

public void testPageDisplayed() throws Exception {

Book command = new Book();

command.setId(1);

ModelAndView modelAndView =

BookDetailsController.testHandle(command);

assertEquals("The bookdetails page should be displayed",

"bookdetails",

modelAndView.getViewName());

}

public void testBookDetailsFound() throws Exception {

BookDetailsCommand command = new BookDetailsCommand();

command.setId(1);

ModelAndView modelAndView =

bookDetailsController.testHandle(command);

Map model = modelAndView.getModel();

Book book = (Book) model.get("book");

assertEquals("The book should have been found",

1,

book.getId());

}

}

Kao što možemo vidjeti, svaka test metoda radi manje ili više iste stvari : postavlja komandni

objekt Knjiga, dodjeljuje mu ID, koji onda prenosi u DetaljiKnjigeKontrolor i dobija

ModelIPogled objekat nazad. Dvije metode testStranicaPrikazana() i

testDetaljiKnjigePronađeni() dodjeljuju ID broj 1, postojeći ID knjige iz razloga što su obje

metode u osnovi iste. Čini se da bi imalo smisla da prebacimo kod u setUp().

38

Page 39: Ddt dizajn vođen testiranjem final

Stavljanjem koda u setUp(), dali bi do znanja da je ovo test postavka koda, a ne test kod, pa zbog

toga, prebacujemo ga u odvojene metode. Evo rezultirajućeg test koda (refaktorisani kod je

prikazan crvenom bojom):

private Book command;

public void setUp() throws Exception {

command = new Book();

command.setId(1);

}

public void testPageDisplayed() throws Exception {

ModelAndView modelAndView = callTestHandle();

assertEquals("The bookdetails page should be displayed.",

"bookdetails",

modelAndView.getViewName());

}

public void testBookDetailsFound() throws Exception {

ModelAndView modelAndView = callTestHandle();

Map model = modelAndView.getModel();

Book book = (Book) model.get("book");

assertEquals("The book should have been found.",

1,

book.getId());

}

private ModelAndView callTestHandle() {

return bookDetailsController.testHandle(command);

}

39

Page 40: Ddt dizajn vođen testiranjem final

Pokretanjem ove klase testova, dobijamo crvene oznake svugdje zato što rukovanje() metoda još

uvijek vraća nulu, što možemo popraviti. Da zaokružimo ovaj test slučaj, možemo sad sigurno

dodati realni kod u rukovanje() metodu u DetaljiKnjigeKontrolor:

protected ModelAndView handle(

HttpServletRequest request,

HttpServletResponse response,

Object command,

BindException errors) throws Exception {

Book book = (Book) command;

book.load(bookDao);

return new ModelAndView("bookdetails", "book", book);

}

Pokretanjem ovog koda kroz različite testere jedinica dobijamo zeleno svjetlo, što znači da je test

zadovoljio.

2.6. Testiranje Prikaz Stranica Knjiga Nije Pronađena Kontrolor (Display Book

Not Found Page Controller)

U završnom test slučaju, testiramo alternativne kurseve u kojima je ID knjige ne postoji. Tekst

korištenog slučaja, koji povezuje sa ovim test slučajem je:

ALTERNATIVNI KURSEVI:

Knjiga nije pronađena: Sistem prikazuje stranicu Detalji Knjige Nisu Pronađeni

Slika 12. prikazuje test scenario koji je dodat u EA za ovaj test slučaj.

40

Page 41: Ddt dizajn vođen testiranjem final

Tu su dva test scenarija: “Stranica Knjiga Nije Pronađena Prikazana” i “Detalji Knjige Nisu

Pronađeni” . Oba ova scenarija su kategorizovana kao alternativni test scenariji, koji imaju

smisla zato što je ovo test slučaj za kontrolora na alternativnom kursu u korištenom slučaju.

Slika 13. prikazuje izvod sekvencijalnog dijagrama koji pokriva dizajn za ovaj alternativni kurs.

Slika 12. Test scenarij za Knjiga Nije Pronađena kontrolor/test slučaj

41

Page 42: Ddt dizajn vođen testiranjem final

Slika 13. Izvod iz sekvencijalnog dijagrama Prikaži detalje knjige za alternativne kurseve

Pisanje kostura koda za klasu testa jedinica je jednostavna stvar prolaska kroz test scenarije za

ovaj test slučaj i dodavanje test metode za svaki scenario. Test metode su prikazane crvenom

bojom u slijedećem kodu:

public class DisplayBookNotFoundPageTest extends TestCase {

public DisplayBookNotFoundPageTest(String testName) {

super(testName);

}

public void setUp() throws Exception {

}

public void tearDown() throws Exception {

}

public void testBookNotFoundPageDisplayed() throws Exception {

42

Page 43: Ddt dizajn vođen testiranjem final

}

public void testBookDetailsNotFound() throws Exception {

}

}

Osnovni kod za ovu klasu će biti identičan osnovnom kodu prethodnog test slučaja. Zapravo, kod

koji ide u obje test metode je takođe veoma sličan. Slika 14. prikazuje dvije klase koje bi trebale

biti spojene.

.

Slika 14. Dijagram klase za dva test slučaja Detalji Knjige (prvi pokušaj)

43

Page 44: Ddt dizajn vođen testiranjem final

Problem sa ovim dizajnom je taj da kada pokrenemo StranicaPrikazKnjigaNijePronađenaTest,

test iz “roditeljske” klase testova će se takođe pokrenuti. Možemo uzeti “promodernistički”

pristup i izbjeći “naslijedstvo”u korist agregacije. Drugim riječima, možemo premjestiti

zajednički kod u odvojene pomoćne klase za oba test slučaja.(slika 15.)

Slika 15. Dijagram klase za dva Detalji knjige test slučaja

Završit ćemo ovo poglavlje sa 10 najvećih grešaka dizajnom vođenog testiranja.

44

Page 45: Ddt dizajn vođen testiranjem final

3. Deset najvećih grešaka dizajna vođenog testiranjem

Slijedi lista 10 najvećih grešaka koje ne bi trebali raditi:

10. Pretjerivati sa mock(lažnim) objektima.

9. Duplicirati scenarije alternativnih kurseva u alternativne test scenarije za osnovne kurs

kontrolore.

8. Zaboraviti da povežemo testove sa zahtjevima.

7. Ostaviti testiranje nakon što je napisan kod.

6. Zamijeniti testiranje sa dizajnom.

5. Ignorisati vruće tačke problema.

4. Koristiti nasilno testiranje umjesto identifikovanje, pa onda ciljanje “vrućih tački” iz

preliminarnog dizajna.

3. Koristiti pogrešnu vrstu testiranja za pogrešnu situaciju.

2. Zaboraviti uraditi testiranje uopće.

1. Testirati toliko temeljito da nikada ne objavite proizvod.

45

Page 46: Ddt dizajn vođen testiranjem final

Slika 16. Aktivnosti testiranja u toku faze implementacije

46

Page 47: Ddt dizajn vođen testiranjem final

Zaključak

U ovom poglavlju pokrili smo različite oblike korištenih slučajeva – vođenih testiranjem i opisali

kada bi trebali koristiti svaki od njih. Dizaj vođen testiranjem je metoda koja nam omogućava

proizvodnju test slučajeva, kako bi se uvjerili da su svi naznačeni scenariji. Ovu metodu možemo

takođe koristiti da napišemo izvršne testove testnih slučajeva. Naveli smo i definisali vrste

testova koje se koriste i objasnili kako i kada se oni koriste.

Takođe smo prošli kroz primjer dizajna vođenog testiranjem na primjeru Internet knjižare i

napisali neke testove jedinica da pokrijemo Prikaži Detalje Knjige – korišteni slučaj.

Slika 16. pokazuje gdje smo trenutno. Aktivnosti koje su urađene u ovom poglavlju su prikazane

crvenom bojom. Omogućili smo detaljan prikaz i diskusiju primjera urađenog u Agilnom

dodataku ICONIX Procces-a u Enterprise Arhitect-u. Dodavanje osnovnih i alternativnih

scenarija kao i postupak transformiranja robusnih dijagrama u sekvencijali ili dijagram test

slučaja.

Jedna od ključnih tački u ovom poglavlju je da testovi ne dokazuju puno ako nisu uvezani na

mikroskopskom nivou sa zahtjevima.

Na kraju smo naveli 10 greški koje nikako ne bismo trebali činiti u procesu testiranja. U

slijedećem poglavlju govorit ćemo o zahtjevima i pokazat ćemo kako se oni uklapaju u ukupni

proces.

47

Page 48: Ddt dizajn vođen testiranjem final

Bibliografija

D. Rosenberg, M Stephens, Use case driven object modeling with UML: Theory and

Practice, 2007.god.

48

Page 49: Ddt dizajn vođen testiranjem final

Popis slika i tabela

Slike:

Slika 1. „V“ model softverskog testiranja primjenjljivog u ICONIX Procces-u

Slika 2. Pregled DDT-a

Slika 3. Korištenje Agilnog ICONIX/EA dodatka za generiranje dijagrama

Slika 4. Generacija test slučajeva u EA

Slika 5. Dodavanje test scenarija u EA

Slika 6. Generirani test slučaj za prikaži detalje knjige korišteni slučaj

Slika 7. Dodavanje test scenarija za test slučaj Prikaz početne stranice

Slika 8. Izvod iz sekvencijalnog dijagrama Prikaži početnu stranicu

Slika 9. Test scenario za Preuzmi detalje Knjige

Slika 10. Test scenario za Prikaži Detalje knjige kontrolor/test slučaj

Slika 11. Izvod iz sekvencijalnog dijagrama Prikaži Detalje Knjige

Slika 12. Test scenarij za Knjiga Nije Pronađena kontrolor/test slučaj

Slika 13. Izvod iz sekvencijalnog dijagrama Prikaži detalje knjige za alternativne kurseve

Slika 14. Dijagram klase za dva test slučaja Detalji Knjige (prvi pokušaj)

Slika 15. Dijagram klase za dva Detalji knjige test slučaja

Slika 16. Aktivnosti testiranja u toku faze implementacije

Tabele:

Tabela 1. Različite vrste testova i kada ih primjeniti

Tabela 2. Testovi koji prolaze kroz razvojni proces

49