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 veți testa manual codul?

Ar trebui să faceți aceste două 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ă scrieți teste unitare în Python și veți vedea cât de ușor este să le puneți în funcțiune în propriul dvs. 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:

#Generate a formatted full name
def formatted_name(first_name, last_name):
   full_name = first_name + ' ' + last_name
   return full_name.title()

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:

from name_function import formatted_name

print("Please enter the first and last names or enter x to E[x]it.")

while True:
   first_name = input("Please enter the first name: ")
   if first_name == "x":
       print("Good bye.")
       break

   last_name = input("Please enter the last name: ")
   if last_name == "x":
       print("Good bye.")
       break

   result = formatted_name(first_name, last_name)
   print("Formatted name is: " + result + ".")

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 împreună demonstrează că o funcție funcționează așa cum se intenționează, într-o gamă completă de situații în care funcția respectivă 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 care să reprezinte 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:

import unittest
from name_function import formatted_name

class NamesTestCase(unittest.TestCase):

   def test_first_last_name(self):
       result = formatted_name("pete", "seeger")
       self.assertEqual(result, "Pete Seeger")

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 dvs. formatat_nume (). 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 de testare 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 literele mari cu majusculă, 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 () prin includerea unui nou argument de prenume.

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

#Generate a formatted full name including a middle name
def formatted_name(first_name, last_name, middle_name):
   full_name = first_name + ' ' + middle_name + ' ' + last_name
   return full_name.title()

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:

Error
Traceback (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 la 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ă formatat_nume () 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 la funcția noastră 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 ():

#Generate a formatted full name including a middle name
def formatted_name(first_name, last_name, middle_name=""):
   if len(middle_name) > 0:
       full_name = first_name + ' ' + middle_name + ' ' + last_name
   else:
       full_name = first_name + ' ' + last_name
   return full_name.title()

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. A venit 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:

import unittest
from name_function import formatted_name

class NamesTestCase(unittest.TestCase):

    def test_first_last_name(self):
        result = formatted_name("pete", "seeger")
        self.assertEqual(result, "Pete Seeger")

    def test_first_last_middle_name(self):
        result = formatted_name("raymond", "reddington", "red")
        self.assertEqual(result, "Raymond Red Reddington")

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.


Mulțumesc că ai citit! Consultați mai multe articole de acest fel pe profilul meu Routech: https://www.freecodecamp.org/news/author/goran/ și alte lucruri distractive pe care le construiesc pe pagina mea GitHub: https://github.com/GoranAviani