Dio 1 – Greška, defekt, otkaz
Dio 2 – Sedam principa testiranja
Dio 3 – Tester i DeliveryApp
Praksa – prvi test olovkom i Pythonom
Materijale priredio Erkan Islamović
erkan.islamovic@eubd.edu.ba · erkan.islamovic@gmail.com
Petnaest sedmica: svaka ima tri časa teorije i tri časa praktične nastave. Danas: poglavlje 1 (Sedmica 1, označeno). Isti primjer kroz knjigu: DeliveryApp, narudžba N-1001.
| Sed. | Poglavlje | Teorija (3 časa) | Praksa (3 časa) |
|---|---|---|---|
| 1 | Zašto testiramo | Uvodne priče; greška, defekt, otkaz; sedam principa; DeliveryApp | Tabela očekivanih cijena rukom |
| 2 | Proces i nivoi | Test proces; nivoi i V-model; vrste; statičko testiranje | Recenzija zahtjeva DeliveryApp |
| 3 | Manuelno testiranje | Test slučaj; izvještaj o defektu; istraživačko testiranje | Test slučajevi za web stranicu |
| 4 | Automatizovano testiranje | Šta automatizovati; piramida testova; prvi test | Prvi pytest |
| 5 | Jedinično testiranje | AAA; fixture, parametri, izuzeci; TDD | Testovi za dostavu i popust |
| 6 | Bijela kutija | Graf toka; pokrivenost; ciklomatska složenost | coverage.py do 100 % grana |
| 7 | Tok podataka | Definicija i upotreba; anomalije; statička analiza, mutacije | ruff, mypy, ručna mutacija |
| 8 | Crna kutija | Ekvivalencija i granice; tabela odlučivanja; stanja | Lov na pet grešaka |
| Sed. | Poglavlje | Teorija (3 časa) | Praksa (3 časa) |
|---|---|---|---|
| 9 | Model i integracija | Model; strategije integracije; API | TestClient za API |
| 10 | Sistemsko testiranje | Sistemsko; performanse i sigurnost; prihvatno i BDD | Locust, Gherkin |
| 11 | OO testiranje | Stanje objekta; nasljeđivanje; dvojnici | Narudzba, unittest.mock |
| 12 | Paralelne aplikacije | Trka podataka; zastoj; nestabilni testovi | Niti, 1000 ponavljanja |
| 13 | Web aplikacije | Web i DOM; Playwright; Page Object, pristupačnost | Playwright za DeliveryApp |
| 14 | Upravljanje testiranjem | Test plan i rizik; metrike; CI/CD | GitHub Actions |
| 15 | Alati, AI, projekat | Pregled alata; AI u testiranju; ISTQB | Odbrana projekta |
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.
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.
| Č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? |
| 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 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:
if iznos > 3000: umjesto if iznos >= 3000:.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.

> umjesto >=, i kupac s 30,00 € plati dostavu.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.
Četiri razloga, od najočitijeg do najvažnijeg:
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.

Odgovori: tipka R ili klik na zamućeno polje.
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.
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
Č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).
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.
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. |

Odgovori: tipka R ili klik na zamućeno polje.
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:
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.
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 € |
Kupac K-01 naručuje iz Picerije R-1 dvije pizze Margarita i jedan sok, na adresu 4,2 km od restorana:
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.
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:
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.
„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.
Odgovori: tipka R ili klik na zamućeno polje.
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.
primjeri/deliveryapp/ iz repozitorija udžbenika (ili ga dobijte od nastavnika) i otvorite ga u VS Codeu.deliveryapp-testovi za svoje rezultate tokom semestra i u njega dodajte README.md s imenom i predmetom.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:
student10) i kod s razmacima (" STUDENT10 ");Sve rezultate izračunajte olovkom ili kalkulatorom, prije pokretanja programa.
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 -> OTKAZANAPonovite isto s prvom verzijom: umjesto from deliveryapp import … napišite from deliveryapp_v0 import …. Zapišite stvarne rezultate u treću kolonu.
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.
Rješenja su sakrivena – tipka R ili klik na okvir.
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”.
a) ljudska greška; b) defekt u kodu; c) otkaz; d) defekt u dokumentu (specifikaciji), koji može navesti na ljudsku grešku.
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?
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.
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.
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 €.
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.”
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).
Prepišite rečenicu tako da opisuje defekt, a ne osobu: „Marko je opet zeznuo popust, ne radi s malim slovima.”
„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.