Uvod u testiranje na Pythonu

Upravo ste završili s pisanjem koda i pitate se što učiniti. Hoćete li predati zahtjev za povlačenjem i zatražiti od suigrača da pregledaju kôd ili ćete ga ručno testirati? Trebali biste učiniti sve ove stvari, ali s dodatnim korakom: morate jedinstveno testirati svoj kôd kako biste bili sigurni da kôd radi kako je predviđeno.

Jedinstveni testovi mogu proći ili proći, a to ih čini izvrsnom tehnikom provjere vašeg koda. U ovom uputstvu pokazat ću kako pisati unit testove u Pythonu i kako je lako pokrenuti ih u vašem projektu.

Početak rada

Najbolji način na koji možete razumjeti testiranje je ako to radite izravno. U tu svrhu, u datoteku koja se zove name_function.py, napisat ću jednostavnu funkciju koja uzima ime i prezime i vraća puno ime:

Funkcija formatted_name () uzima ime i prezime i kombinira ih s razmakom između njih kako bi oblikovala puno ime. Zatim se velikim slovom stavlja prvo slovo svake riječi. Da biste provjerili radi li ovaj kod, trebate napisati neki kôd koji koristi ovu funkciju. U names.py napisat ću jednostavan kod koji omogućava korisnicima da unose svoja imena i prezimena:

Ovaj kôd uvozi formatted_name () iz name_function.py i pri pokretanju, omogućuje korisniku unos niza imena i prezimena i prikazuje formatirana puna imena.

Jedinstveni test i test slučajevi

U Pythonovoj standardnoj knjižnici postoji modul nazvan unittest koji sadrži alate za testiranje vašeg koda. Jedinstveno testiranje provjerava jesu li svi specifični dijelovi ponašanja vaše funkcije ispravni, što će im olakšati integraciju zajedno s ostalim dijelovima.

Test case je zbirka jediničnih testova koja zajedno dokazuje da funkcija radi kako je predviđeno, unutar čitavog niza situacija u kojima se ta funkcija može naći i za koje se očekuje da će je riješiti. Test slučaj trebao bi razmotriti sve moguće vrste unosa koje funkcija može dobiti od korisnika, te bi stoga trebao uključiti testove koji predstavljaju svaku od ovih situacija.

Polaganje testa

Evo tipičnog scenarija za pisanje testova:

Prvo morate stvoriti testnu datoteku. Zatim uvezite unittest modul, definirajte klasu testiranja koja se nasljeđuje od unittest.TestCase i na kraju napišite niz metoda za testiranje svih slučajeva ponašanja vaše funkcije.

Ispod sljedećeg koda nalazi se objašnjenje reda po redak:

Prvo morate uvesti unittest i funkciju koju želite testirati, formatted_name (). Zatim izradite klasu, na primjer NamesTestCase, koja će sadržavati testove za vašu funkciju formatted_name (). Ova klasa nasljeđuje od klase unittest.TestCase.

NamesTestCase sadrži jednu metodu koja testira jedan dio formatted_name (). Ovu metodu možete nazvati test_first_last_name ().

Imajte na umu da će se svaka metoda koja započinje s "test_" pokrenuti automatski kada pokrenete test_name_function.py.

Unutar test metode test_first_last_name () pozivate funkciju koju želite testirati i pohranjujete povratnu vrijednost. U ovom ćemo primjeru pozvati formatted_name () s argumentima "pete" i "seeger", a rezultat ćemo pohraniti u rezultirajuću varijablu.

U posljednjem ćemo retku koristiti metodu assert. Metoda potvrde potvrđuje da se rezultat koji ste dobili podudara s rezultatom koji ste očekivali. I u ovom slučaju znamo da će funkcija formatted_name () vratiti puno ime s velikim početnim slovima, pa očekujemo rezultat "Pete Seeger". Da bi se to provjerilo, koristi se unittest-ova metoda assertEqual ().

self.assertEqual(result, “Pete Seeger”)

Ovaj redak u osnovi znači: Usporedite vrijednost rezultirajuće varijable s "Pete Seeger" i ako su jednake, u redu je, ali ako mi se ne jave.

Na pokretanju test_name_function.py očekuje se da ćete dobiti OK što znači da je test prošao.

Ran 1 test in 0.001s
OK

Neuspjeh na testu

Da bih vam pokazao kako izgleda neuspjeli test, izmijenit ću funkciju formatted_name () tako što ću uključiti novi argument srednjeg imena.

Dakle, prepisat ću funkciju kako bi izgledala ovako:

Ova verzija formatted_name () radit će za ljude sa srednjim imenima, ali kada je testirate, vidjet ćete da je funkcija slomljena za ljude koji nemaju srednje ime.

Dakle, kada pokrenete test_name_function.py dobit ćete izlaz koji izgleda otprilike ovako:

ErrorTraceback (most recent call last):
File “test_name_function.py”, line 7, in test_first_last_name result = formatted_name(“pete”, “seeger”)
TypeError: formatted_name() missing 1 required positional argument: ‘middle_name’
Ran 1 test in 0.002s
FAILED (errors=1)

U izlazu ćete vidjeti informacije koje će vam reći sve što trebate znati gdje test ne uspije:

  • Prva stavka u izlazu je Greška koja vam govori da je barem jedan test u testnom slučaju rezultirao pogreškom.
  • Dalje ćete vidjeti datoteku i metodu u kojoj je došlo do pogreške.
  • Nakon toga vidjet ćete redak u kojem se dogodila pogreška.
  • I o kakvoj se pogrešci radi, u ovom nam slučaju nedostaje 1 argument "srednje_ime".
  • Vidjet ćete i broj pokrenutih testova, vrijeme potrebno za završetak testova i tekstualnu poruku koja predstavlja status testova s ​​brojem pogrešaka koje su se dogodile.

Što učiniti kada test nije uspio

Prolazni test znači da se funkcija ponaša u skladu s onim što se od nje očekuje. Međutim, neuspjeli test znači da je pred vama još zabave.

Vidio sam nekoliko programera koji radije mijenjaju test umjesto da poboljšavaju kôd - ali nemojte to učiniti. Provedite malo više vremena da riješite problem jer će vam to pomoći da bolje razumijete kôd i dugoročno uštedite vrijeme.

U ovom primjeru, naša funkcija formatted_name () prvo je trebala dva parametra, a sada kako je prepisana zahtijeva jedan dodatni: srednje ime. Dodavanje srednjeg imena našoj funkciji slomilo je željeno ponašanje. Budući da ideja nije mijenjati testove, najbolje je rješenje učiniti srednje ime neobveznim.

Nakon što to učinimo, ideja je da testovi prođu kada se koriste ime i prezime, na primjer "Pete Seeger", kao i kada se koriste prvo, prezime i srednje ime, na primjer "Raymond Red Reddington". Pa hajde da još jednom izmijenimo kod formatted_name ():

Sada bi funkcija trebala raditi za imena sa i bez srednjeg imena.

Da biste bili sigurni da i dalje radi s "Pete Seegerom", pokrenite test ponovo:

Ran 1 test in 0.001s
OK
I ovo sam vam namjeravao pokazati: Uvijek je bolje unijeti promjene u svoj kod kako bi odgovarao vašim testovima, nego obrnuto. Sad je došlo vrijeme da se doda novi test za imena koja imaju srednje ime.

Dodavanje novih testova

Napišite novu metodu u klasu NamesTestCase koja će testirati srednja imena:

Nakon pokretanja testa, oba bi testa trebala proći:

Ran 2 tests in 0.001s
OK
Grudnjak! Bravo!

Napisali ste svoje testove kako biste provjerili radi li funkcija pomoću imena sa ili bez srednjeg imena. Pratite nas za drugi dio gdje ću govoriti više o testiranju na Pythonu.

Ove i druge zabavne stvari koje radim mogu se naći na mom Githubu: //github.com/GoranAviani