de Goran Aviani

O introducere la testarea în Python

O introducere la testarea in Python

Tocmai ați terminat de scris o bucată de cod și vă întrebați ce să faceți. Vei trimite o cerere de extragere și îi vei solicita pe colegii tăi de echipă să verifice codul sau vei testa manual codul? Ar trebui să faceți toate aceste lucruri, dar cu un pas suplimentar: trebuie să testați unitatea codului pentru a vă asigura că codul funcționează conform intenției.

Testele unitare pot trece sau nu, ceea ce le face o tehnică excelentă pentru a vă verifica codul. În acest tutorial voi demonstra cum să scriu teste unitare în Python și cât de ușor este să le faci să meargă în propriul tău proiect.

Noțiuni de bază

Cel mai bun mod în care puteți înțelege testarea este dacă îl faceți manual. În acest scop, într-un fișier numit name_function.py, voi scrie o funcție simplă care ia un nume și prenume și returnează un nume complet:

Funcția formatted_name () ia numele și prenumele și le combină cu un spațiu între pentru a forma un nume complet. Apoi, scrie cu majusculă prima literă din fiecare cuvânt. Pentru a verifica dacă acest cod funcționează, trebuie să scrieți un cod care utilizează această funcție. În names.py voi scrie un cod simplu care permite utilizatorilor să introducă numele și prenumele:

Acest cod importă formatted_name () din name_function.py și în curs de rulare, permite utilizatorului să introducă o serie de nume și prenume și afișează numele complete formatate.

Test de unitate și cazuri de testare

Există un modul în biblioteca standard a Python numit unittest care conține instrumente pentru testarea codului dvs. Testarea unității verifică dacă toate părțile specifice ale comportamentului funcției dvs. sunt corecte, ceea ce va facilita integrarea acestora împreună cu alte părți.

Test case este o colecție de teste unitare care demonstrează împreună că o funcție funcționează așa cum se intenționează, într-o gamă completă de situații în care funcția se poate găsi și pe care se așteaptă să o gestioneze. Cazul de testare trebuie să ia în considerare toate tipurile posibile de intrare pe care o funcție le-ar putea primi de la utilizatori și, prin urmare, ar trebui să includă teste pentru a reprezenta fiecare dintre aceste situații.

Trecerea unui test

Iată un scenariu tipic pentru scrierea testelor:

Mai întâi trebuie să creați un fișier de testare. Apoi importați modulul unittest, definiți clasa de testare care moștenește de la unittest.TestCase și, în cele din urmă, scrieți o serie de metode pentru a testa toate cazurile de comportament al funcției dvs.

Există o explicație rând cu rând sub următorul cod:

Mai întâi, trebuie să importați unitest și funcția pe care doriți să o testați, formatat_nume (). Apoi creați o clasă, de exemplu, NamesTestCase, care va conține teste pentru funcția formatted_name (). Această clasă moștenește din clasa unittest.TestCase.

NamesTestCase conține o singură metodă care testează o parte a formatted_name (). Puteți apela această metodă test_first_last_name ().

Amintiți-vă că fiecare metodă care începe cu „test_” va fi rulată automat atunci când rulați test_name_function.py.

În cadrul metodei test test_first_last_name (), apelați funcția pe care doriți să o testați și stocați o valoare returnată. În acest exemplu vom apela formatted_name () cu argumentele „pete” și „seeger” și vom stoca rezultatul în variabila rezultată.

În ultima linie vom folosi metoda asert. Metoda asert verifică dacă un rezultat pe care l-ați primit se potrivește cu rezultatul pe care vă așteptați să îl primiți. Și în acest caz știm că funcția formatted_name () va returna numele complet cu majuscule, așa că ne așteptăm la rezultatul „Pete Seeger”. Pentru a verifica acest lucru, se folosește metoda unertest assertEqual ().

self.assertEqual(result, “Pete Seeger”)

Această linie înseamnă practic: Comparați valoarea variabilei rezultate cu „Pete Seeger” și dacă sunt egale este OK, dar dacă nu sunt anunțați-mă.

La rularea test_name_function.py, este de așteptat să obțineți un OK care înseamnă că testul a trecut.

Ran 1 test in 0.001s
OK

Eșecul unui test

Pentru a vă arăta cum arată un test care nu reușește, voi modifica o funcție formatted_name (), incluzând un nou argument de prenume.

Deci, voi rescrie funcția pentru a arăta astfel:

Această versiune de formatted_name () va funcționa pentru persoanele cu nume de mijloc, dar când o testați, veți vedea că funcția este întreruptă pentru persoanele care nu au un prenume.

Deci, atunci când rulați test_name_function.py, veți obține rezultatul care arată așa:

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)

În rezultat veți vedea informații care vă vor spune tot ce trebuie să știți unde eșuează testul:

  • Primul element din ieșire este Eroarea care vă spune că cel puțin un test în cazul testului a dus la o eroare.
  • Apoi veți vedea fișierul și metoda în care a apărut eroarea.
  • După aceea, veți vedea linia în care a apărut eroarea.
  • Și ce fel de eroare este, în acest caz ne lipsește un argument „middle_name”.
  • Veți vedea, de asemenea, numărul de teste efectuate, timpul necesar finalizării testelor și un mesaj text care reprezintă starea testelor cu numărul de erori care au apărut.

Ce trebuie făcut atunci când testul a eșuat

Un test de trecere înseamnă că funcția se comportă în funcție de ceea ce se așteaptă de la ea. Cu toate acestea, un test eșuat înseamnă că aveți mai multă distracție în fața dvs.

Am văzut câțiva programatori care preferă să schimbe testul în loc să îmbunătățească codul – dar nu fac asta. Petreceți puțin mai mult timp pentru a remedia problema, deoarece vă va ajuta să înțelegeți mai bine codul și să economisiți timp pe termen lung.

În acest exemplu, funcția noastră formatted_name () a cerut mai întâi doi parametri, iar acum, pe măsură ce este rescris, necesită un supliment: un nume de mijloc. Adăugarea unui nume de mijloc funcției noastre a spart comportamentul dorit al acesteia. Deoarece ideea nu este de a face modificări la teste, cea mai bună soluție este de a face numele de mijloc opțional.

După ce facem acest lucru, ideea este să facem testele să treacă atunci când sunt folosite numele și prenumele, de exemplu „Pete Seeger”, precum și când sunt folosite numele, prenumele și mijlocul, de exemplu „Raymond Red Reddington”. Deci, să modificăm încă o dată codul formatted_name ():

Acum funcția ar trebui să funcționeze pentru nume cu și fără numele de mijloc.

Și pentru a vă asigura că funcționează în continuare cu „Pete Seeger” rulați din nou testul:

Ran 1 test in 0.001s
OK

Și asta am intenționat să vă arăt: este întotdeauna mai bine să modificați codul pentru a se potrivi testelor dvs. decât invers. Acum a sosit momentul să adăugăm un nou test pentru numele care au un nume de mijloc.

Adăugarea de noi teste

Scrieți o metodă nouă în clasa NamesTestCase care va testa numele de mijloc:

După ce rulați testul, ambele teste ar trebui să treacă:

Ran 2 tests in 0.001s
OK

Bra gjort!

Foarte bine!

Ați scris testele pentru a verifica dacă funcția funcționează folosind nume cu sau fără un prenume. Rămâneți la curent cu partea 2, unde voi vorbi mai multe despre testarea în Python.

Acest lucru și alte lucruri distractive pe care le fac pot fi găsite pe Github: https://github.com/GoranAviani