Prestanite pisati unit testove za sve, pišite ih za pravu stvar

8. rujna 2026.

Ilustracija štita koji pokriva samo dio koda dok ostatak prolazi kroz mrežu testova bottom cut

Prestanite pisati unit testove za sve, pišite ih za pravu stvar

Naslijedili smo projekt s 94% test coveragea. Zvuči kao san, zar ne? Onda smo u prvom tjednu pustili u produkciju bug koji je krivo računao PDV na narudžbama iznad određenog iznosa. Sve zeleno u CI-ju, sve prošlo. Ispalo je da postoji test koji poziva funkciju za izračun cijene, dobije rezultat i onda ga nigdje ne provjeri. Doslovno calculatePrice(order) bez ijednog expect. Coverage alat je tu liniju obojao zeleno jer se izvršila. Nitko nikad nije provjerio je li rezultat točan.

To je srž problema s coverageom kao ciljem. Coverage mjeri je li se kod izvršio, ne je li itko provjerio što je vratio. To su dvije potpuno različite stvari, a mi ih godinama brkamo jer je jedan broj lako staviti u dashboard, a drugi zahtijeva razmišljanje.

100% coverage nije cilj, nego crvena zastava

Kad vidim tim koji cilja na 100% coverage, ne vidim disciplinu. Vidim tim koji piše testove da zadovolji broj, a ne da uhvati greške. Jer da biste došli do zadnjih dvadesetak posto, morate testirati getere, setere, trivijalne konstruktore, jednolinijske mapiranja objekata i grane koje se u praksi nikad ne dogode. Ti testovi ne hvataju ništa. Oni samo postoje da bi broj bio lijep.

Gori dio dolazi kasnije. Svaki takav test je teret. Kad promijenite implementaciju, tridesetak testova pukne, ne zato što ste nešto pokvarili, nego zato što su vezani za to kako je nešto napisano, a ne za to što bi trebalo raditi. Tim provede pola dana krpajući testove umjesto isporučivanja. I onda ljudi počnu mrziti testove, što je najgori mogući ishod, jer sad im testovi smetaju umjesto da pomažu.

Nije stvar u broju. Projekt s 60% coveragea koji pokriva svu poslovnu logiku, rubne slučajeve i integracije oko naplate zdraviji je od projekta s 95% koji testira gettere i preskače ono gdje se stvarno gubi novac.

Gdje testovi stvarno vrijede

Postoji jednostavno pitanje koje si postavljam prije nego napišem test: ako ovo pukne u produkciji, koliko boli? Ako je odgovor "nitko ne bi ni primijetio", nemam što tu testirati. Ako je odgovor "netko dobije krivi račun" ili "izgubimo narudžbu", to je mjesto gdje se testira do besvijesti.

Konkretno, ovo su mjesta gdje test skoro uvijek vrati uloženo:

  • Poslovna logika s rubnim slučajevima. Izračuni cijena, popusti, porezi, granice, zaokruživanje. Sve gdje "plus jedan" ili "minus jedan" mijenja ishod.
  • Sve što dira novac ili podatke korisnika. Naplata, autorizacija, izmjene stanja u bazi.
  • Bug koji ste upravo popravili. Prije nego popravite, napišite test koji reproducira grešku. To je jedini test za koji sigurno znate da bi nešto uhvatio, jer je već jednom uhvatio.
  • Složene transformacije i parsiranje. Sve gdje ulaz može biti neuredan, a izlaz mora biti točan.

A gdje ne trošiti vrijeme? Na trivijalnom kodu bez logike, na frameworku (ne testirate tuđu biblioteku), i na stvarima koje se ionako bolje hvataju integracijskim testom nego s dvadeset izoliranih unit testova s pola tuceta mockova. Kad se u testu pojavi više mockova nego stvarnog koda, to je znak da testirate svoju maštu o sustavu, ne sam sustav.

Coverage koji laže: problem s AI-generiranim testovima

Ovo je postalo hitno zadnjih godinu i pol. Kažete alatu "napiši mi testove za ovaj modul" i za trideset sekundi dobijete lijep set koji podigne coverage na 90%. Izgleda kao poklon. Problem je što AI odlično piše testove koji se izvršavaju, ali koji provjeravaju premalo ili provjeravaju krivu stvar. Dobijete gomilu expect(result).toBeDefined() umjesto provjere je li rezultat zapravo točan. Kod se izvršio, coverage je zelen, a test ne bi uhvatio ni da funkcija vraća potpuno pogrešan broj.

Tu prestaje coverage kao mjera i počinje ono što stvarno vrijedi provjeriti: mutation testing. Ideja je jednostavna i pomalo genijalna. Alat namjerno pokvari vaš kod, promijeni > u >=, obrne uvjet, zamijeni + s -, i onda pusti vaše testove. Ako testovi i dalje prolaze na pokvarenom kodu, znači da ništa ne provjeravaju. Preživjela mutacija je dokaz da je test teatar.

Kad smo prvi put pustili mutation testing (Stryker za jedan JS projekt) na modul koji je imao 88% coveragea, mutation score je bio ispod 50%. Prevedeno: pola naših "provjera" ne bi primijetilo da je kod pokvaren. To je bio trenutak kad je cijeli tim prestao gledati coverage kao mjeru sigurnosti. Ne trebate mutation testing na cijelom sustavu, presporo je i preskupo. Ali na kritičnoj poslovnoj logici i na svemu što je napisao AI, to je jedini pošten način da provjerite jesu li vaši testovi stvarni ili su samo zeleni.

Što napraviti u ponedjeljak ujutro

Ako imate projekt s visokim coverageom u kojem se svejedno pojavljuju bugovi, ne dodavajte još testova. Napravite obrnuto:

  1. Prestanite ciljati na broj. Maknite prag "moraš imati X% da bi mergeao" ako vas tjera da pišete testove bez asertacija. Zamijenite ga pregledom: testira li ovaj test nešto što stvarno može puknuti?
  2. Pustite mutation testing na najkritičniji modul. Samo jedan, za početak. Rezultat će vas otrijezniti.
  3. Za svaki bug koji dođe u produkciju napišite test prije popravka. To je jedini test za koji imate dokaz da radi.
  4. AI-generirane testove tretirajte kao skicu, ne kao gotov posao. Pročitajte svaku asertaciju. Ako je nema, test ne postoji, samo zauzima mjesto.

Cilj nikad nije bio imati puno testova. Cilj je spavati mirno jer znate da će vas nešto probuditi ako se pokvari ono što je bitno. To se ne mjeri postotkom.

Povezano:

Ako niste sigurni hvataju li vaši testovi ono što je bitno, ili samo pune dashboard, mi to znamo prepoznati. Javite nam se i pogledat ćemo gdje vam je testiranje stvarna zaštita, a gdje samo skupi teatar.

Zatražite ponudu u samo 10 sekundi.

Bez ikakvih obveza.

computer guy

Prijavite se na newsletter

Besprijekorna digitalna

rješenja

Naši uredi
Pratite nas
facebook twitter linkedin