Poglavlje 1: Zašto testiramo
Ovo je prvo poglavlje, pa se ne nastavlja ni na šta: dovoljno je da ste nekad koristili aplikaciju koja nije radila kako ste očekivali. Prije prve definicije pogledaćemo pet istinitih priča. Četiri govore o greškama koje su koštale milione, rakete i dane zastoja na aerodromima. Peta govori o timu koji je pisao softver s gotovo nijednom greškom, i kako je to postigao. Iz priča izlazi pitanje na koje odgovara cijeli predmet: kako pronaći grešku prije nego što je pronađe korisnik?
U drugom dijelu poglavlja razdvajamo riječi koje se često miješaju (greška, defekt, otkaz) i objašnjavamo šta testiranje jeste, a šta nije. Zatim učimo sedam principa testiranja, koji važe za svaki projekat. U trećem dijelu upoznajemo DeliveryApp, izmišljenu aplikaciju za naručivanje hrane koju testiramo kroz cijelu knjigu, i njenih šest pravila. Na praktičnoj nastavi pravimo prvi „test” olovkom: tabelu očekivanih cijena, i poredimo je s onim što program zaista izračuna.
Literatura. Osnovna literatura predmeta:
- J. Popović: Priručnik za test inženjere, CET i Računarski fakultet, Beograd, 2023.
- Rakić-Skoković: Priručnik za testiranje softvera, Fakultet tehničkih nauka, Novi Sad, 2013.
- G. J. Myers: The Art of Software Testing, 2. izdanje, John Wiley & Sons, 2004.
- A. P. Mathur: Foundations of Software Testing, Addison-Wesley Professional, 2008.
Riječi ovog poglavlja.
- Greška (ljudska) – ono što čovjek pogrešno uradi ili pomisli dok piše zahtjev ili kod.
- Defekt (bug) – mjesto u kodu, dokumentu ili modelu koje je pogrešno zbog ljudske greške.
- Otkaz (failure) – trenutak kad sistem u radu uradi nešto pogrešno, vidljivo korisniku.
- Testiranje – provjera softvera radi otkrivanja defekata i procjene kvaliteta, prije nego što stigne do korisnika.
- Debagovanje – traženje i popravljanje uzroka otkaza u kodu; to radi programer poslije testa.
- Test slučaj – jedan zadatak za provjeru: ulaz, koraci i očekivani rezultat.
- Očekivani rezultat – ono što sistem treba da uradi po pravilima; s njim poredimo stvarni rezultat.
- Test orakul – izvor iz kojeg znamo očekivani rezultat (specifikacija, ručni račun, stara verzija).
- Pokrivenost – koliki dio programa ili pravila su testovi provjerili.
- Regresija – greška koja se pojavi u nečemu što je ranije radilo, poslije neke izmjene.
- Kvalitet – koliko softver ispunjava zahtjeve i očekivanja korisnika.
- ISTQB – međunarodna organizacija koja definiše pojmove i ispite za testere.
Ciljevi poglavlja. Nakon poglavlja možete: ispričati bar dvije priče o greškama u softveru i reći šta bi ih otkrilo; razlikovati ljudsku grešku, defekt i otkaz na primjeru; objasniti šta je testiranje i po čemu se razlikuje od debagovanja; navesti razloge zašto testiramo; nabrojati i objasniti sedam principa testiranja; izračunati zašto iscrpno testiranje nije moguće ni za malu funkciju; opisati ulogu testera u timu; navesti šest pravila DeliveryApp i izračunati cijenu narudžbe N-1001; napraviti tabelu očekivanih rezultata i uporediti je sa stvarnim rezultatima programa.
Plan poglavlja – Sedmica 1: tri časa teorije i tri časa praktične nastave
| Čas | Sadržaj | Na času |
|---|---|---|
| Teorija 1 | Uvodne priče; 1.1 Greška, defekt, otkaz | Moljac, Ariane 5, Knight, CrowdStrike, šatl |
| Teorija 2 | 1.2–1.6 Šta je testiranje; sedam principa | 959 601 kombinacija za jednu funkciju |
| Teorija 3 | 1.7–1.9 Tester u timu; DeliveryApp; test orakul | N-1001 rukom: 24,50 € |
| Praksa 1–3 | Tabela očekivanih cijena; pokretanje dvije verzije DeliveryApp | Koliko neslaganja nalazite? |
Uvodne priče – kad mala greška napravi veliku štetu
Prije prve definicije, pet istinitih priča. Nijedna greška u njima nije bila genijalna ni neuhvatljiva. Svaku je mogao naći jedan dobro izabran test, postavljen u pravo vrijeme. A posljednja priča pokazuje da je moguće pisati softver skoro bez grešaka, ako se testiranje shvati ozbiljno.
Ljudi, mjesta, godine i brojevi u ovim pričama su stvarni. Izvori su u SADRZAJ.md (Izvori priča) i u Dodacima.
Priča 1 – Moljac u releju (Harvard, 1947)
Septembar 1947. U laboratoriji Univerziteta Harvard radi Mark II, jedan od prvih velikih računara. Nema ekrana ni tastature kakve znamo. Računar je ogroman ormar pun releja: malih elektromagnetnih prekidača koji škljocaju dok računaju. Računar radi pogrešno, a niko ne zna zašto.
Tim koji radi na računaru, među kojima je i matematičarka Grace Hopper, kasnije jedna od najpoznatijih žena u istoriji računarstva, traži kvar. I nalazi ga, doslovno: u jednom releju zaglavio se moljac. Neko iz tima ga je izvadio i zalijepio selotejpom u dnevnik rada, uz bilješku na engleskom: „First actual case of bug being found” („prvi stvarni slučaj da je pronađena buba”). Ta stranica dnevnika, s moljcem, i danas se čuva u Nacionalnom muzeju američke istorije Smithsonian u Washingtonu.
Šala u bilješci krije zanimljiv detalj: riječ „bug” (buba) za kvar u uređaju bila je u upotrebi i ranije; koristio ju je, na primjer, Thomas Edison još 1878. Tim na Harvardu se našalio upravo zato što je ovaj put buba bila prava. Od tada se u računarstvu greška u programu zove bug, a njeno traženje i uklanjanje debagovanje (od engleskog debugging, „otklanjanje buba”).
Pouka za testera: greška se ne nalazi gledanjem u računar i nadanjem. Nalazi se sistematskim traženjem i zapisivanjem, kao u tom dnevniku. Dnevnik s moljcem je, na neki način, prvi izvještaj o defektu.
Ukratko.
- U septembru 1947. tim računara Mark II na Harvardu pronašao je moljca zaglavljenog u releju.
- Moljac je zalijepljen u dnevnik rada uz bilješku „prvi stvarni slučaj da je pronađena buba”, i stranica se čuva u muzeju Smithsonian.
- Riječ „bug” za kvar postojala je i ranije, ali od tada je simbol greške u softveru.
- Pouka je da se greške nalaze sistematskim traženjem i zapisivanjem.
Priča 2 – Broj koji nije stao (Ariane 5, 1996)
Četvrtog juna 1996. Evropska svemirska agencija lansira prvu raketu novog tipa, Ariane 5, iz Francuske Gvajane u Južnoj Americi. Na raketi su četiri naučna satelita. Raketa se diže sa zemlje, a nakon oko 37 sekundi od paljenja motora naglo skreće s putanje, počinje se raspadati i sama se uništava. Nema povrijeđenih, ali su raketa i sateliti izgubljeni, a godine rada odletjele su u dim.
Istražna komisija je ubrzo našla uzrok, i on je bio skoro neugodno mali. Softver koji je određivao položaj rakete preuzet je s prethodne rakete, Ariane 4, gdje je godinama radio bez greške. U tom softveru jedan broj (vezan za horizontalnu brzinu rakete) čuvao se kao 64-bitni decimalni broj, a onda se pretvarao u 16-bitni cijeli broj. Šesnaest bita može sačuvati brojeve najviše do 32 767. Na Ariane 4 taj broj nikad nije bio toliko velik. Ali Ariane 5 je bila mnogo jača raketa i ubrzavala je brže, pa je broj prerastao granicu. Pretvaranje je izazvalo grešku koju program nije obradio, računar za navođenje se ugasio, a rezervni računar, s istim softverom, ugasio se zbog iste greške.
Komisija je zapisala i ono najvažnije: provjere i testovi nisu obuhvatili ponašanje tog dijela softvera u uslovima leta nove rakete. Softver je bio „dobro testiran”, ali za drugu raketu.
Pouka za testera: granice su mjesto gdje se kriju greške (o tome je poglavlje 8), a softver preuzet iz drugog sistema mora se ponovo testirati u novim uslovima.
Ukratko.
- Prva Ariane 5 uništena je 4. juna 1996, oko 37 sekundi nakon paljenja motora.
- Uzrok je bilo pretvaranje 64-bitnog decimalnog broja u 16-bitni cijeli, koji ne može biti veći od 32 767.
- Softver je preuzet s Ariane 4, gdje broj nikad nije bio toliko velik, i nije testiran za uslove nove rakete.
- Rezervni računar s istim softverom otkazao je zbog iste greške.
- Pouka je da se granice testiraju posebno i da se preuzet softver testira u novim uslovima.
Priča 3 – Četrdeset pet minuta (Knight Capital, 2012)
Ujutro 1. augusta 2012. američka firma Knight Capital, jedan od najvećih posrednika na njujorškoj berzi, pustila je u rad novu verziju programa za automatsko trgovanje dionicama. Program se instalirao na osam servera, ručno. Na jednom od njih nova verzija nije instalirana, a tamo je ostao stari kod koji se godinama nije koristio. Nova verzija je ponovo upotrijebila jednu oznaku koja je nekad uključivala baš taj stari kod.
Kad je berza otvorena, taj jedan server počeo je slati ogroman broj naloga za kupovinu i prodaju koje niko nije tražio. Za oko 45 minuta, dok je tim shvatio šta se dešava i zaustavio sistem, firma je izgubila oko 440 miliona dolara. Da bi preživjela, za nekoliko dana morala je pronaći nove investitore.
Novi program nije bio loš. Loše je bilo to što niko nije provjerio da je isti program na svih osam servera, da stari kod više ne postoji i da sistem ima dugme „stani”. Takve provjere zovu se testovi isporuke i dim-testovi (smoke tests), i o njima govore poglavlja 2 i 14.
Ukratko.
- Knight Capital je 1. augusta 2012. pustio novi program na osam servera, a na jednom je ostao stari kod.
- Za oko 45 minuta pogrešni nalozi koštali su firmu oko 440 miliona dolara.
- Nije provjereno da je ista verzija na svim serverima ni da stari kod više ne postoji.
- Pouka je da se testira i sama isporuka, a ne samo program.
Priča 4 – Jedna datoteka, milioni računara (CrowdStrike, 2024)
Petak, 19. jula 2024. Ujutro, na aerodromima širom svijeta ekrani za polaske postaju plavi. Banke ne mogu obrađivati plaćanja, televizijske stanice ne mogu emitovati, a neke bolnice odgađaju operacije. Računari s operativnim sistemom Windows prikazuju „plavi ekran” i ne mogu se pokrenuti.
Uzrok nije bio napad hakera. Firma CrowdStrike, koja pravi sigurnosni softver što radi duboko unutar Windowsa, poslala je svojim korisnicima jednu novu konfiguracionu datoteku, rutinsko ažuriranje. Datoteka je sadržavala grešku koju softver nije znao obraditi, a pošto taj softver radi u samom jezgru sistema, greška je oborila cijeli računar. Ažuriranje je poslano svim korisnicima skoro istovremeno. Microsoft je procijenio da je pogođeno oko 8,5 miliona Windows uređaja, što je manje od jedan posto svih, ali dovoljno da danima stoje aerodromi i bolnice.
Kasniji izvještaji i rasprave stručnjaka ponavljali su dvije pouke za testere: i „mala” izmjena, poput konfiguracione datoteke, mora proći testove kao i kod; i izmjena se šalje postepeno, prvo malom broju računara, tako da se greška vidi prije nego što stigne do svih.
Ukratko.
- Dana 19. jula 2024. pogrešna konfiguraciona datoteka firme CrowdStrike oborila je Windows računare širom svijeta.
- Microsoft je procijenio oko 8,5 miliona pogođenih uređaja; stajali su aerodromi, banke i bolnice.
- Ažuriranje je poslano svima skoro istovremeno.
- Pouka je da se testira i svaka konfiguraciona izmjena i da se izmjene šalju postepeno.
Priča 5 – Softver koji je letio u svemir (svemirski šatl, 1981–2011)
Posljednja priča je drugačija. Od 1981. do 2011. američki svemirski šatlovi letjeli su u orbitu i nazad. Njima je upravljao računarski program od nekoliko stotina hiljada redova, a pisao ga je i održavao jedan tim u Teksasu. Greška u tom programu mogla je ubiti posadu.
Novinar Charles Fishman je 1996. godine o tom timu napisao članak „They Write the Right Stuff” („Oni pišu pravu stvar”). Prema članku, posljednje tri verzije programa, svaka od oko 420 000 redova, imale su po samo jednu grešku. Kako? Ne genijalnošću, nego procesom: svaki zahtjev je bio zapisan do detalja prije programiranja; svaka izmjena prolazila je kroz pregled; poseban tim je imao jedini posao da traži greške, i tražio ih je kao takmičenje; i svaka pronađena greška se analizirala pitanjem „kako je proces dopustio da ova greška nastane, i kako ga promijeniti da se to ne ponovi?”.
Takav nivo pažnje nije potreban svakom programu; aplikacija za naručivanje hrane nije svemirski šatl. Ali priča pokazuje da greške nisu sudbina. Broj grešaka zavisi od toga koliko pažljivo tim traži i koliko uči iz onih koje nađe.
Ukratko.
- Softver svemirskih šatlova (1981–2011) bio je jedan od najpouzdanijih programa ikad napisanih.
- Prema članku iz 1996, posljednje tri verzije, svaka od oko 420 000 redova, imale su po jednu grešku.
- Tajna je bila proces: zapisani zahtjevi, pregled svake izmjene, poseban tim za traženje grešaka i učenje iz svake.
- Pouka je da broj grešaka zavisi od pažnje tima, a ne od sreće.
Šta je zajedničko svim pričama
| Priča | Šta je pošlo naopako | Koji test bi pomogao | Poglavlje |
|---|---|---|---|
| Moljac, 1947 | fizički kvar u releju | sistematsko traženje i zapisivanje | 3 |
| Ariane 5, 1996 | broj prerastao granicu od 32 767 | test granične vrijednosti u uslovima nove rakete | 8, 10 |
| Knight Capital, 2012 | stari kod na jednom od osam servera | test isporuke, dim-test, nadzor | 2, 14 |
| CrowdStrike, 2024 | neispravna datoteka poslata svima | test konfiguracije, postepena isporuka | 10, 14 |
| Šatl, 1981–2011 | (skoro ništa) | pregledi, nezavisno testiranje, učenje iz grešaka | 2, 14 |
U nijednoj priči testiranje ne bi bilo skupo. Skupa je bila njegova odsutnost.

Ukratko.
- Nijedna greška iz priča nije bila neuhvatljiva; svaku je mogao naći dobro izabran test.
- Ariane 5 i Knight pokazuju važnost granica i provjere isporuke.
- Softver šatla pokazuje da pažljiv proces daje skoro savršen softver.
- Skupo nije bilo testiranje, nego njegova odsutnost.
Dio 1 – Greška, defekt, otkaz
1.1 Tri riječi koje se miješaju
U svakodnevnom govoru kažemo „aplikacija ima grešku” i za ono što je programer pogrešno napisao, i za ono što korisnik vidi na ekranu. Tester mora biti precizniji, jer su to tri različite stvari, u lancu:
- Ljudska greška (error, mistake): čovjek pogrešno razumije ili pogrešno uradi. Programer pročita pravilo „za artikle od 30,00 € i više dostava je besplatna” i pomisli „preko 30 €”.
- Defekt (defect, fault, bug): rezultat te greške ostane zapisan negdje, u kodu, dokumentu ili modelu. U kodu piše
if iznos > 3000:umjestoif iznos >= 3000:. - Otkaz (failure): kad se defektni dio izvrši u pravim uslovima, sistem uradi nešto pogrešno, i to se vidi. Kupac naruči za tačno 30,00 € i aplikacija mu naplati 3,00 € dostave.
Primijetite da defekt može postojati godinama bez otkaza. Ako niko ne naruči za tačno 30,00 €, defekt > umjesto >= nikad se ne pokaže. Kod Ariane 5 defekt je postojao i na Ariane 4, ali otkaz se desio tek kad je raketa bila dovoljno brza. Zato testeri namjerno stvaraju uslove u kojima se defekt pokaže: biraju baš 30,00 €.
Slika iz života: kuhar i recept. Kuhar pogrešno pročita „2 kašičice soli” kao „2 kašike” (ljudska greška) i tako zapiše u svesku recepata (defekt). Svaki put kad neko skuha po toj svesci, jelo je preslano (otkaz). Jelo je otkaz, sveska je defekt, a pogrešno čitanje je ljudska greška. Ako popravimo samo jelo (dosolimo vodom), sljedeće će opet biti preslano; treba popraviti svesku, i pitati se kako da se pogrešno čitanje ne ponovi.

Ukratko.
- Ljudska greška je pogrešno razumijevanje ili postupak; defekt je njen trag u kodu ili dokumentu; otkaz je pogrešno ponašanje koje se vidi.
- Programer pomisli „preko 30 €”, napiše
>umjesto>=, i kupac s 30,00 € plati dostavu.- Defekt može dugo postojati bez otkaza, pa testeri namjerno biraju uslove u kojima se pokazuje.
- Kao kod recepta: popravlja se sveska, a ne samo jelo.
1.2 Šta je testiranje, a šta nije
Testiranje je skup aktivnosti kojima se softver i dokumenti oko njega provjeravaju da bi se otkrili defekti i procijenio kvalitet, prije nego što softver stigne do korisnika. Međunarodna organizacija ISTQB (International Software Testing Qualifications Board), koja definiše pojmove i ispite za testere širom svijeta, naglašava da testiranje nije samo pokretanje programa. U njega spadaju i čitanje zahtjeva, pregled koda, planiranje i izvještavanje.
Česta zabuna je između testiranja i debagovanja:
| Testiranje | Debagovanje | |
|---|---|---|
| cilj | pokazati da otkaz postoji | naći i popraviti uzrok otkaza |
| ko radi | tester (i programer) | programer |
| rezultat | izvještaj o defektu: šta, kada, kako ponoviti | izmijenjen kod |
| pitanje | „Da li radi kako treba?” | „Zašto ne radi?” |
Tester kaže: „Za tačno 30,00 € na 5 km aplikacija naplaćuje dostavu 3,00 €; po PP-4 treba 0,00 €.” Programer zatim debaguje: pronađe red s >, ispravi ga u >=, i ponovo pokrene test da potvrdi ispravku.
Druga važna razlika je između verifikacije i validacije. Verifikacija pita: radi li softver ono što piše u specifikaciji? Validacija pita: radi li ono što korisniku zaista treba? Softver može tačno raditi po specifikaciji, a specifikacija može biti pogrešna. Testeri provjeravaju oboje.
Ukratko.
- Testiranje je provjera softvera i dokumenata radi otkrivanja defekata i procjene kvaliteta.
- Testiranje uključuje i čitanje zahtjeva, preglede, planiranje i izvještaje, a ne samo pokretanje programa.
- Testiranje pokazuje da otkaz postoji; debagovanje nalazi i popravlja uzrok.
- Verifikacija provjerava prema specifikaciji, a validacija prema stvarnim potrebama korisnika.
1.3 Zašto testiramo
Četiri razloga, od najočitijeg do najvažnijeg:
- Da nađemo defekte prije korisnika. Defekt koji nađe tester košta vrijeme jednog programera. Isti defekt koji nađe korisnik košta i nezadovoljnog kupca, i popravku pod pritiskom, a nekad i milione (Knight) ili raketu (Ariane 5).
- Da smanjimo rizik. Testiranje ne može dokazati da grešaka nema, ali može smanjiti vjerovatnoću da se ozbiljna greška desi u radu, posebno u najvažnijim dijelovima (plaćanje, cijena).
- Da sakupimo dokaz o kvalitetu. Naručilac, šef i ponekad zakon traže odgovor na pitanje „smijemo li ovo pustiti?”. Rezultati testova su taj odgovor, napisan brojevima.
- Da tim uči. Svaki pronađeni defekt govori nešto o procesu: zašto je nastao i kako ga sljedeći put spriječiti, kao tim šatla.
Cijena defekta raste s vremenom. Defekt pronađen dok je pravilo samo rečenica u zahtjevu ispravlja se brisanjem riječi. Isti defekt pronađen u kodu traži izmjenu koda i testova. Pronađen kod korisnika traži sve to, plus štetu koju je već napravio. Mnoga istraživanja pokazuju da ta cijena raste i desetostruko između ranih i kasnih faza; tačan faktor zavisi od projekta, ali smjer je uvijek isti.

Ukratko.
- Testiramo da nađemo defekte prije korisnika, smanjimo rizik, sakupimo dokaz o kvalitetu i naučimo iz grešaka.
- Testiranje ne dokazuje da grešaka nema, ali smanjuje vjerovatnoću ozbiljnih otkaza.
- Cijena ispravke defekta raste što se kasnije otkrije.
Provjeri se.
- Šta je otkaz? – Trenutak kad sistem u radu uradi nešto pogrešno što se vidi.
- Ko debaguje, a ko testira? – Programer debaguje (nalazi i popravlja uzrok), a tester pokazuje da otkaz postoji.
- Može li defekt postojati bez otkaza? – Da; dok se defektni dio ne izvrši u pravim uslovima, otkaza nema.
Dio 2 – Sedam principa testiranja
ISTQB opisuje sedam principa koji važe za svako testiranje, od male aplikacije do rakete. Svaki od njih štedi vrijeme jer sprečava pogrešna očekivanja.
1.4 Principi 1 i 2: šta testiranje može, a šta ne
Princip 1: Testiranje pokazuje prisustvo defekata, ne njihovo odsustvo. Ako test padne, sigurno znamo da defekt postoji. Ako svi testovi prođu, znamo samo da u onome što smo testirali nismo našli defekt. Zato tester nikad ne kaže „nema grešaka”, nego „za ovih 40 slučajeva sistem radi po pravilima”.
Princip 2: Iscrpno testiranje je nemoguće. Iscrpno znači isprobati sve moguće ulaze. Pogledajmo samo jednu funkciju DeliveryApp, cijena_dostave(udaljenost, iznos). Ako bi iznos bio cijeli broj centi od 5,00 € do 100,00 €, to je 10 000 − 500 + 1 = 9501 vrijednost. Ako bi udaljenost bila zaokružena na desetinku kilometra od 0 do 10 km, to je 101 vrijednost. Svih kombinacija je
\[ N = 9501 \times 101 = 959\,601. \]
Čemu služi. Račun pokazuje da već jedna mala funkcija ima skoro milion kombinacija, a mi smo je pojednostavili: udaljenost u stvarnosti nije zaokružena (3,01 km, 3,001 km…), iznos može biti veći od 100 €, a tu su i kod popusta, stanje narudžbe i redoslijed koraka. Za cijelu aplikaciju broj mogućih ulaza je praktično beskonačan. Zato tester bira testove pametno: tehnikama koje biraju malo slučajeva koji otkriju mnogo defekata (poglavlja 5 do 9) i prema riziku (poglavlje 14).
Ukratko.
- Testiranje pokazuje prisustvo defekata, ali ne može dokazati njihovo odsustvo.
- Iscrpno testiranje je nemoguće: samo cijena_dostave ima 9501 × 101 = 959 601 pojednostavljenih kombinacija.
- Zato se testovi biraju tehnikama i prema riziku.
1.5 Principi 3, 4 i 5: kada i gdje tražiti
Princip 3: Rano testiranje štedi vrijeme i novac. Testiranje počinje što ranije: već čitanje zahtjeva je test. Kad tester pročita PP-4 i pita „a šta je s tačno 30,00 €?”, nađen je defekt u zahtjevu prije nego što je napisan ijedan red koda. Ovo se zove i „pomjeranje ulijevo” (shift left), jer se na vremenskoj liniji projekta testiranje pomjera prema početku.
Princip 4: Defekti se grupišu. Defekti nisu ravnomjerno raspoređeni. Često je mali dio programa odgovoran za veliki dio defekata: dijelovi koji su složeni, često mijenjani ili pisani pod pritiskom. U DeliveryApp je to vjerovatno obračun cijene, s mnogo pravila i granica. Dobar tester troši više vremena tamo gdje su defekti već nađeni, jer ih tamo vjerovatno ima još.
Princip 5: Testovi se troše. Ako se isti testovi ponavljaju iznova, s vremenom prestanu nalaziti nove defekte, jer programeri ispravljaju upravo ono što ti testovi provjeravaju. Ovo se nekad zvalo i paradoks pesticida: kao što insekti postanu otporni na isti otrov, tako i softver „postane otporan” na iste testove. Testovi se zato redovno pregledaju i dopunjuju novim slučajevima.
Slika iz života za princip 4: ribar. Ako je na jednom mjestu na rijeci ulovio pet riba, tamo će opet zabaciti udicu, a ne nasumično po cijeloj rijeci.
Ukratko.
- Rano testiranje štedi: pitanje o granici u zahtjevu nalazi defekt prije koda.
- Defekti se grupišu u složenim i često mijenjanim dijelovima, pa se tamo traži više.
- Testovi se troše: isti testovi s vremenom prestanu nalaziti nove defekte, pa se dopunjuju.
1.6 Principi 6 i 7: kontekst i zabluda
Princip 6: Testiranje zavisi od konteksta. Softver svemirskog šatla i aplikacija za naručivanje hrane ne testiraju se isto. Za šatl greška može ubiti posadu, pa se testira svaka grana koda. Za DeliveryApp greška u boji dugmeta je sitnica, ali greška u cijeni je ozbiljna. Tester bira tehnike, dubinu i alate prema tome šta je u pitanju.
Princip 7: Zabluda o odsustvu defekata. Ni softver bez ijednog poznatog defekta nije uspjeh ako ne radi ono što korisniku treba. Ako DeliveryApp savršeno računa cijenu, ali je naručivanje toliko zbunjujuće da kupci zovu restoran telefonom, sistem nije dobar. Ovo je opet razlika između verifikacije i validacije: testiramo i da li je sistem ispravno napravljen i da li je napravljen pravi sistem.
| Princip | Jedna rečenica |
|---|---|
| 1 | Test može pokazati da greška postoji, ne da je nema. |
| 2 | Sve kombinacije se ne mogu isprobati; biramo pametno. |
| 3 | Što ranije počnemo, to jeftinije. |
| 4 | Gdje je bila jedna greška, vjerovatno ima još. |
| 5 | Stari testovi s vremenom prestanu nalaziti nove greške. |
| 6 | Šatl i aplikacija za hranu ne testiraju se isto. |
| 7 | Bez grešaka, a nekorisno, nije uspjeh. |

Ukratko.
- Testiranje zavisi od konteksta: šatl i aplikacija za hranu testiraju se različito.
- Softver bez poznatih defekata nije uspjeh ako ne radi ono što korisniku treba.
- Sedam principa štedi vrijeme jer sprečava pogrešna očekivanja od testiranja.
Provjeri se.
- Šta tester smije reći kad svi testovi prođu? – Da za testirane slučajeve sistem radi po pravilima, a ne da grešaka nema.
- Koliko pojednostavljenih kombinacija ima cijena_dostave? – 9501 × 101 = 959 601.
- Šta znači da se testovi troše? – Ponavljani isti testovi s vremenom prestanu nalaziti nove defekte.
Dio 3 – Tester i DeliveryApp
1.7 Tester u timu
Tester nije „neprijatelj programera” ni policajac koji traži krivca. Tester i programer imaju isti cilj: da korisnik dobije softver koji radi. Razlika je u pogledu. Programer gleda kako nešto napraviti; tester gleda šta bi moglo poći naopako. Oba pogleda su potrebna, i zato je dobro da kod ne testira samo onaj ko ga je napisao: autor teško vidi grešku u vlastitom razmišljanju, kao što pisac teško vidi slovnu grešku u vlastitom tekstu.
Dobar tester ima nekoliko osobina:
- radoznalost – voli pitati „a šta ako…?” (šta ako je udaljenost 0? negativna? 10,0001?);
- sumnjičavost prema očitom – „to sigurno radi” je rečenica koja ga natjera da provjeri;
- preciznost – izvještaj o defektu piše tako da ga drugi može ponoviti u minuti;
- takt – piše o defektu, a ne o osobi: „za 30,00 € dostava je 3,00 €, treba 0,00 €”, a ne „opet si pogriješio”.
Tester ne mora biti posebna osoba. U mnogim timovima programeri pišu automatske testove za svoj kod, a testeri se bave težim stvarima: istraživanjem, sistemskim testovima, rizikom. Ali pogled testera mora postojati u timu, bez obzira ko ga nosi.
Ukratko.
- Tester i programer imaju isti cilj; tester gleda šta bi moglo poći naopako.
- Autor teško vidi grešku u vlastitom razmišljanju, pa je dobro da testira i neko drugi.
- Dobar tester je radoznao, sumnjičav prema očitom, precizan i taktičan.
- Pogled testera mora postojati u timu, ma ko ga nosio.
1.8 Upoznajemo DeliveryApp
Kroz cijelu knjigu testiramo jedan izmišljeni sistem: DeliveryApp, aplikaciju za naručivanje hrane u jednom malom gradu. U njoj naručuju kupci (K-01 do K-05) iz tri restorana: R-1 Picerija, R-2 Roštilj i R-3 Salatarnica, a hranu nose dostavljači D-1 do D-4. Isti sistem se projektuje u predmetu Projektovanje informacionih sistema.
DeliveryApp mora poštovati šest poslovnih pravila (oznaka PP):
| Oznaka | Pravilo |
|---|---|
| PP-1 | Najmanja narudžba je 5,00 € (zbir artikala); manje se odbija. |
| PP-2 | Dostava je 2,00 € do 3 km, plus 0,50 € za svaki započeti kilometar preko 3 km. |
| PP-3 | Dostava ide od 0 do najviše 10 km; negativna ili veća udaljenost se odbija. |
| PP-4 | Za artikle od 30,00 € i više dostava je besplatna. |
| PP-5 | Kod STUDENT10 (velika ili mala slova, razmaci na krajevima se zanemaruju) daje 10 % popusta na artikle, najviše 5,00 €. Besplatna dostava gleda iznos prije popusta. |
| PP-6 | Kupac smije otkazati narudžbu u stanju NOVA ili PRIHVAĆENA; od stanja U_PRIPREMI više ne. |
Jelovnik u primjerima:
| Restoran | Jelo | Cijena |
|---|---|---|
| R-1 | Pizza Margarita | 9,50 € |
| R-1 | Pizza Capricciosa | 11,00 € |
| R-1 | Sok | 2,50 € |
| R-2 | Ćevapi (10 komada) | 8,00 € |
| R-2 | Pljeskavica | 7,50 € |
| R-2 | Jogurt | 1,50 € |
| R-3 | Salata s piletinom | 9,00 € |
| R-3 | Voćna salata | 4,50 € |
| R-3 | Limunada | 3,00 € |
Narudžba N-1001, rukom
Kupac K-01 naručuje iz Picerije R-1 dvije pizze Margarita i jedan sok, na adresu 4,2 km od restorana:
- Artikli: 2 × 9,50 + 2,50 = 21,50 €.
- PP-1: 21,50 € nije manje od 5,00 €; narudžba se prima.
- PP-3: 4,2 km je između 0 i 10 km; adresa je u zoni.
- PP-4: 21,50 € je manje od 30,00 €; dostava se plaća.
- PP-2: preko 3 km je 1,2 km, a to su dva započeta kilometra; dostava je 2,00 + 2 × 0,50 = 3,00 €.
- Ukupno: 21,50 + 3,00 = 24,50 €. Sa kodom STUDENT10: popust 2,15 €, ukupno 22,35 €.
Broj za pamćenje. Narudžba N-1001 košta 24,50 €. Ako bilo koja verzija DeliveryApp pokaže drugi broj, našli smo otkaz.
Dvije verzije koda
Kod DeliveryApp je napisan u Pythonu i nalazi se u folderu primjeri/deliveryapp/. Postoje dvije verzije:
deliveryapp.py– ispravna verzija;deliveryapp_v0.py– prva verzija, koju su programeri napisali u žurbi. U njoj je nekoliko defekata, namjerno ostavljenih za vježbu.
Koliko defekata ima prva verzija i gdje su, ne otkrivamo. Tražićemo ih kroz knjigu tehnikama koje učimo, kao pravi testeri, a u poglavlju 8 pokušaćemo ih naći sve. Iznosi su u kodu zapisani u centima (2450 znači 24,50 €), da bi se izbjegle greške zaokruživanja decimalnih brojeva.
Ukratko.
- DeliveryApp je izmišljena aplikacija za naručivanje hrane s tri restorana, pet kupaca i četiri dostavljača.
- Šest pravila PP-1 do PP-6 su izvor skoro svakog testa u knjizi.
- N-1001 košta 24,50 €, a sa kodom STUDENT10 22,35 €.
- Ispravna verzija je deliveryapp.py, a prva verzija s namjerno ostavljenim defektima deliveryapp_v0.py.
1.9 Test orakul: odakle znamo tačan odgovor
Test ima smisla samo ako znamo šta je tačno. Pokrenuti program i vidjeti da je ispisao „24,00 €” ne govori ništa, ako ne znamo da treba „24,50 €”. Izvor iz kojeg dobijamo očekivani rezultat zove se test orakul (po proročištu u staroj Grčkoj, koje je „znalo” odgovor).
Za DeliveryApp orakuli su:
- specifikacija, odnosno pravila PP-1 do PP-6;
- ručni račun po pravilima, kao za N-1001;
- tabela očekivanih rezultata koju tester napravi unaprijed;
- ponekad druga verzija sistema za koju vjerujemo da je tačna (npr. stara verzija koja je radila godinama).
Evo početka tabele očekivanih rezultata za cijenu dostave, izračunate rukom, prije pokretanja ijednog programa:
| ID | Udaljenost | Artikli | Očekivana dostava | Pravilo i račun |
|---|---|---|---|---|
| T-01 | 2 km | 10,00 € | 2,00 € | PP-2: do 3 km |
| T-02 | 3 km | 10,00 € | 2,00 € | tačno 3 km nije „preko 3 km” |
| T-03 | 3,1 km | 10,00 € | 2,50 € | 0,1 km preko je jedan započeti km |
| T-04 | 4,2 km | 21,50 € | 3,00 € | dva započeta km (N-1001) |
| T-05 | 10 km | 10,00 € | 5,50 € | 2,00 + 7 × 0,50 |
| T-06 | 11 km | 10,00 € | odbijeno | PP-3 |
| T-07 | 5 km | 30,00 € | 0,00 € | PP-4: „od 30,00 € i više” |
| T-08 | 5 km | 29,99 € | 3,00 € | 2,00 + 2 × 0,50 |
| T-09 | 1 km | 4,99 € | odbijeno | PP-1 |
Primijetite kako su izabrani: većina redova je na granici nekog pravila (3 km, 10 km, 30,00 €, 5,00 €). Upravo tamo se, kao kod Ariane 5, najčešće kriju defekti. Kako se ovakve vrijednosti biraju sistematski, uči poglavlje 8.
Česta zabluda. „Očekivani rezultat ćemo vidjeti kad pokrenemo program.” Ako očekivani rezultat uzmemo iz programa, test provjerava samo da program radi isto kao on sam, a to je uvijek tačno. Očekivani rezultat se zapisuje prije pokretanja, iz pravila.
Ukratko.
- Test orakul je izvor očekivanog rezultata: specifikacija, ručni račun, tabela ili provjerena verzija.
- Očekivani rezultat se zapisuje prije pokretanja programa, iz pravila.
- Dobra tabela ima mnogo slučajeva na granicama pravila (3 km, 10 km, 5,00 €, 30,00 €).
Provjeri se.
- Kolika je dostava za 3,1 km i artikle od 10,00 €? – 2,50 €, jer je započet jedan kilometar preko 3 km.
- Šta je test orakul? – Izvor iz kojeg znamo očekivani rezultat, npr. pravila ili ručni račun.
- Zašto se očekivani rezultat ne uzima iz programa? – Jer bi test tada provjeravao samo da program radi isto kao on sam.
Praktična nastava – prvi test olovkom i Pythonom
Cilj je da svaki student napravi tabelu očekivanih rezultata za DeliveryApp rukom, zatim pokrene obje verzije koda i uporedi rezultate. Ovo je najjednostavnije testiranje: bez alata za testiranje, samo pravila, olovka i Python.
Korak 1 – Priprema
- Instalirajte Python 3 (u učionici je instaliran) i VS Code sa ekstenzijom Python.
- Preuzmite folder
primjeri/deliveryapp/iz repozitorija udžbenika (ili ga dobijte od nastavnika) i otvorite ga u VS Codeu. - Napravite GitHub repozitorij
deliveryapp-testoviza svoje rezultate tokom semestra i u njega dodajteREADME.mds imenom i predmetom.
Korak 2 – Tabela očekivanih rezultata (rukom)
U fajl ocekivano.md napravite tabelu od najmanje 15 redova kao u 1.9: ID, ulaz, očekivani rezultat i račun po pravilu. Neka tabela obuhvati:
- bar pet udaljenosti na granicama i oko njih (0; 3; 3,01; 10; 10,01 km);
- bar tri iznosa oko granica (4,99; 5,00; 29,99; 30,00 €);
- ukupnu cijenu za N-1001 bez koda i sa kodom STUDENT10;
- kod napisan malim slovima (
student10) i kod s razmacima (" STUDENT10 "); - popust na 80,00 € (očekivano 5,00 €, jer je to gornja granica);
- pokušaj otkazivanja narudžbe u stanju U_PRIPREMI (očekivano: odbijeno, PP-6).
Sve rezultate izračunajte olovkom ili kalkulatorom, prije pokretanja programa.
Korak 3 – Pokretanje ispravne verzije
U terminalu VS Codea, u folderu deliveryapp, pokrenite Python interaktivno (python) i isprobajte:
>>> from deliveryapp import cijena_dostave, popust, ukupno, eur
>>> eur(cijena_dostave(4.2, 2150))
'3,00 €'
>>> eur(ukupno([(950, 2), (250, 1)], 4.2))
'24,50 €'
>>> eur(ukupno([(950, 2), (250, 1)], 4.2, "STUDENT10"))
'22,35 €'
>>> cijena_dostave(11, 1000)
Traceback (most recent call last):
...
ValueError: udaljenost izvan zone dostaveZa svaki red svoje tabele zapišite stvarni rezultat u novu kolonu. Iznosi u funkcijama su u centima: 10,00 € je 1000, a 29,99 € je 2999. Da li se ispravna verzija slaže sa svim vašim očekivanjima? Ako se ne slaže, prvo provjerite svoj račun: i tester može pogriješiti.
Za otkazivanje:
>>> from deliveryapp import Narudzba
>>> n = Narudzba("N-1001")
>>> n.promijeni("PRIHVAĆENA"); n.promijeni("U_PRIPREMI")
>>> n.promijeni("OTKAZANA")
Traceback (most recent call last):
...
ValueError: nedozvoljen prelaz U_PRIPREMI -> OTKAZANAKorak 4 – Pokretanje prve verzije
Ponovite isto s prvom verzijom: umjesto from deliveryapp import … napišite from deliveryapp_v0 import …. Zapišite stvarne rezultate u treću kolonu.
Korak 5 – Neslaganja
- Označite svaki red u kojem se stvarni rezultat prve verzije razlikuje od očekivanog. To su otkazi.
- Za svaki otkaz napišite jednu rečenicu po obrascu: „Za ulaz … očekivano je … (pravilo …), a program vraća … .”
- Prebrojite otkaze. Da li mislite da je svaki otkaz drugi defekt, ili isti defekt može dati više otkaza? (Odgovor ćemo potvrditi u poglavlju 8.)
Korak 6 – AI kao pomoćnik (opcionalno)
Dajte AI asistentu pravila PP-1 do PP-6 i zatražite deset dodatnih slučajeva za vašu tabelu „koji bi mogli otkriti greške”. Za svaki predloženi slučaj sami izračunajte očekivani rezultat po pravilima; AI-jevom očekivanom rezultatu ne vjerujte bez provjere. Zapišite bar jedan slučaj u kojem je AI izračunao pogrešno, ako ga nađete.
Rezultat koji se predaje: link na repozitorij deliveryapp-testovi s fajlom ocekivano.md: tabela od najmanje 15 redova s kolonama za očekivani rezultat, stvarni rezultat ispravne i stvarni rezultat prve verzije, te spisak otkaza zapisanih po obrascu iz koraka 5.
Vježbe
Vježba za studenta 1 – greška, defekt ili otkaz.
Razvrstajte: a) programer misli da „započeti kilometar” znači „cijeli kilometar”; b) u kodu stoji round umjesto zaokruživanja naviše; c) kupac na 3,1 km plati dostavu 2,00 € umjesto 2,50 €; d) u specifikaciji piše „0,50 € po kilometru”, bez riječi „započeti”.
Rješenje. a) ljudska greška; b) defekt u kodu; c) otkaz; d) defekt u dokumentu (specifikaciji), koji može navesti na ljudsku grešku.
Vježba za studenta 2 – iscrpno testiranje.
Funkcija popust(iznos, kod) prima iznos od 5,00 € do 200,00 € u centima i kod koji može biti jedna od 4 vrijednosti (STUDENT10, student10, nepoznat kod, prazno). Koliko je kombinacija? Da li ih je razumno sve isprobati ručno?
Rješenje. Iznosa ima 20 000 − 500 + 1 = 19 501, pa je kombinacija 19 501 × 4 = 78 004. Ručno to nije razumno; automatski bi bilo moguće, ali i dalje ne bi obuhvatilo sve stvarne ulaze (npr. kod s razmacima). Zato se biraju predstavnici i granice.
Vježba za studenta 3 – tabela očekivanih rezultata.
Izračunajte očekivanu ukupnu cijenu: a) 4 × Ćevapi na 2,5 km (N-1002); b) 1 × Voćna salata na 1,8 km (N-1003); c) 2 × Salata s piletinom i 2 × Limunada na 6,5 km sa STUDENT10.
Rješenje. a) Artikli 32,00 €, dostava besplatna (PP-4), ukupno 32,00 €. b) Artikli 4,50 € < 5,00 €: narudžba se odbija (PP-1). c) Artikli 2 × 9,00 + 2 × 3,00 = 24,00 €; dostava: preko 3 km je 3,5 km, četiri započeta km, 2,00 + 4 × 0,50 = 4,00 €; popust 10 % = 2,40 €; ukupno 24,00 − 2,40 + 4,00 = 25,60 €.
Vježba za studenta 4 – princip.
Koji princip testiranja opisuje svaka situacija? a) Tim deset sprintova pokreće istih 30 testova i oni uvijek prođu, ali kupci prijavljuju nove greške. b) Tester pri čitanju zahtjeva pita šta je s tačno 3 km. c) U modulu za obračun nađeno je 12 defekata, a u modulu za profil kupca jedan. d) Šef kaže: „Svi testovi su prošli, znači grešaka nema.”
Rješenje. a) testovi se troše (princip 5); b) rano testiranje (princip 3); c) defekti se grupišu (princip 4); d) testiranje pokazuje prisustvo, ne odsustvo defekata (princip 1).
Vježba za studenta 5 – izvještaj bez krivca.
Prepišite rečenicu tako da opisuje defekt, a ne osobu: „Marko je opet zeznuo popust, ne radi s malim slovima.”
Rješenje. „Kod popusta napisan malim slovima (student10) ne daje popust: za artikle 21,50 € očekivano je 2,15 € (PP-5: velika ili mala slova), a program vraća 0,00 €.” Rečenica kaže ulaz, očekivano, pravilo i stvarni rezultat, bez imena.
Sažetak u pet rečenica
- Moljac iz 1947, Ariane 5 iz 1996, Knight Capital iz 2012. i CrowdStrike iz 2024. pokazuju da male greške prave velike štete, a softver šatla pokazuje da pažljiv proces daje skoro savršen softver.
- Ljudska greška ostavlja defekt u kodu ili dokumentu, a defekt izaziva otkaz tek kad se izvrši u pravim uslovima, pa testeri namjerno biraju takve uslove.
- Testiranje otkriva defekte i procjenjuje kvalitet, uključujući čitanje zahtjeva i preglede, a debagovanje nalazi i popravlja uzrok.
- Sedam principa kaže da testiranje pokazuje prisustvo, a ne odsustvo defekata, da je iscrpno testiranje nemoguće, da rano testiranje štedi, da se defekti grupišu, da se testovi troše, da sve zavisi od konteksta i da softver bez defekata nije uspjeh ako ne koristi korisniku.
- DeliveryApp ima šest pravila i dvije verzije koda, N-1001 košta 24,50 €, a svaki test traži očekivani rezultat zapisan unaprijed iz pravila, odnosno test orakul.