Testovi automatski proveravaju očekivanja.
Debagovanje nam pomaže da pronađemo uzrok problema koji smo već primetili. Automatski testovi proveravaju ponašanje koje očekujemo i mogu nas upozoriti kada kasnija promena slučajno pokvari nešto što je ranije radilo.
# Manual check
print(izracunaj_popust(100, 10))
# Automatic check inside a test
self.assertEqual(izracunaj_popust(100, 10), 90)Ručna provera traži da pročitaš i proceniš izlaz. Automatska assertion provera poredi stvarni rezultat sa očekivanim i javlja da li se podudaraju.
Testovi ne dokazuju da program nema nijednu grešku. Oni proveravaju konkretne slučajeve koje izabereš, zato je važno birati korisne primere.
Jedinični test je mali: Jedinični test obično proverava jedan jasno izdvojen deo programa, kao što su funkcija ili metod, u situaciji koju možeš precizno da opišeš.
import unittest
def saberi(a: int, b: int) -> int:
return a + b
class TestSabiranje(unittest.TestCase):
def test_dva_pozitivna_broja(self):
self.assertEqual(saberi(2, 3), 5)
if __name__ == "__main__":
unittest.main()Uvozimo standardnu biblioteku unittest. unittest.TestCase našoj test klasi daje assertion metode. Metod koji počinje sa test_ prepoznaje se kao test, a assertEqual poredi stvarni rezultat sa očekivanom vrednošću. unittest.main() je koristan kada ovaj fajl pokrećemo direktno, ali testovi mogu da se pokrenu i pomoću python -m unittest.
moj_projekat/
├── kalkulator.py
└── test_kalkulator.py
# kalkulator.py
def saberi(a: int, b: int) -> int:
return a + b
# test_kalkulator.py
import unittest
from kalkulator import saberi
class TestKalkulator(unittest.TestCase):
def test_sabiranje(self):
self.assertEqual(saberi(4, 6), 10)Odvajanje implementacije od njenih testova čuva fokus svakog fajla. Iz foldera projekta pokreni python -m unittest -v; na nekim sistemima koristi python3 -m unittest -v. Opcija -v prikazuje više detalja, a unittest obično pronalazi fajlove kao što je test_kalkulator.py i druge fajlove oblika test*.py.
def test_popust_deset_posto(self):
# Arrange
cena = 200
popust = 10
# Act
rezultat = izracunaj_popust(cena, popust)
# Assert
self.assertEqual(rezultat, 180)Arrange priprema ulazne podatke, Act izvršava ponašanje, a Assert poredi stvarni rezultat sa očekivanim. Ti komentari su korisni dok učiš, ali su jasno ime testa i jasno očekivanje često vredniji od mnogo komentara.
self.assertEqual(saberi(2, 3), 5)
self.assertTrue(10 > 5)
self.assertFalse(10 < 5)assertEqual proverava da li su dve vrednosti jednake. assertTrue proverava istinit izraz, a assertFalse neistinit izraz. Za konkretan očekivani broj ili tekst, assertEqual je obično najjasniji izbor. Sa assertRaises ćemo se upoznati u sledećoj lekciji o izuzecima.
python -m unittest -v
python -m unittest discover -v
# Or, on some systems:
python3 -m unittest -v
python3 -m unittest discover -vPokreni komandu iz odgovarajućeg foldera projekta. Pronalaženje testova i njegov tačan izlaz mogu zavisiti od strukture fajlova i verzije Pythona, ali podrazumevani obrazac za test fajlove je test*.py.
Pažljivo pročitaj rezultat testa
- OK znači da je svaka izvršena assertion provera prošlaRezultat
OKznači da je pokretač testova završio provere i da nijedna assertion provera nije pala. - FAIL znači da assertion provera nije ispunjenaNa primer,
self.assertEqual(10, 12)se normalno izvršava, ali pada zato što su vrednosti različite. - ERROR znači da test nije mogao normalno da se završiNa primer,
rezultat = 10 / 0izaziva neočekivani izuzetak pre nego što kasnija assertion provera može da se izvrši. FAIL i ERROR su različiti tragovi, a ne dokaz da sam Python ne radi. - Koristi uobičajene i rubne slučajeveZa funkciju za popust testiraj 0%, 10%, 100% i cenu 0. Rubni slučaj je granična situacija koju jedan običan primer može da propusti.
- Neka testovi štite od regresijaRegresija nastaje kada kasnija promena pokvari ponašanje koje je ranije radilo. Test može prijaviti FAIL, a zatim ti debagovanje pomaže da pronađeš i ispraviš uzrok. Ne menjaj očekivani rezultat samo da bi test prošao; prvo odluči kakvo je ponašanje ispravno.
Česte početničke greške pri testiranju
- Testiranje samo jednog primeraJedan uspešan primer daje ograničeno poverenje. Dodaj uobičajene i rubne slučajeve koji su važni za funkciju.
- Zaboravljanje prefiksa test_Metod bez očekivanog prefiksa
test_možda neće biti pronađen i pokrenut. - Pokretanje iz pogrešnog folderaProveri folder terminala i imena fajlova pre nego što zaključiš da unittest ne može da pronađe tvoje testove.
- Menjanje očekivanja samo da bi rezultat bio OKIme testa treba da opiše šta test proverava. Istraži da li su implementacija ili očekivani rezultat pogrešni pre nego što promeniš bilo koji od njih.
