Un test, multe cazuri
Majoritatea funcțiilor au nevoie de aceeași verificare pentru multe intrări: valori normale, valori negative, zero, cazuri limită. Dacă copiezi testul de cinci ori, ai cinci locuri de întreținut.
Soluția este un test bazat pe tabel: pune cazurile într-o listă de tupluri — fiecare caz conține un nume, intrările și rezultatul așteptat — și rulează aceeași verificare pentru toate.
Adăugarea unui caz nou înseamnă o singură linie nouă în tabel. Acesta este unul dintre cele mai des întâlnite tipare de testare în codul real.
Tabelul
Cel mai simplu tabel este o listă de tupluri chiar în interiorul testului. Fiecare element este un caz: un nume (pentru mesajul de eșec), intrările și rezultatul așteptat.
Bucla apelează funcția o dată pentru fiecare caz și compară rezultatul. Prima nepotrivire ar opri testul la acel caz, iar mesajul conține numele cazului — așa afli care rând s-a stricat.
Patru cazuri într-un singur tabel
Patru cazuri, o buclă, o verificare. Aici toate trec, așa că rularea arată un singur test trecut. Ca să testezi o a cincea situație, ai adăuga o linie în tabel — bucla rămâne neschimbată.
Ieșire: program Python complet
def add(a, b):
return a + b
def test_add():
cases = [
("unu plus unu", 1, 1, 2),
("pozitiv și negativ", 5, -3, 2),
("ambele negative", -2, -4, -6),
("zerouri", 0, 0, 0),
]
for name, a, b, want in cases:
got = add(a, b)
assert got == want, f"{name}: add({a}, {b}) = {got}; se aștepta {want}"
Un test pentru fiecare caz cu parametrize
pytest poate transforma fiecare rând din tabel în propriul său test: decoratorul @pytest.mark.parametrize primește numele argumentelor și lista de cazuri și apelează funcția de test o dată pentru fiecare rând.
Lista ids dă fiecărui caz un nume. Numele apar acum în ieșirea pytest -v, de exemplu test_add[both_negative]. Fiecare caz trece sau eșuează separat, așa că un rând stricat se observă ușor într-un tabel lung — iar rândurile de după el sunt verificate în continuare.
Fiecare caz primește un nume
Același tabel, scris sub formă de cazuri parametrize. Ieșirea detaliată afișează acum toate cele patru cazuri separat — vezi exact ce cazuri au rulat și au trecut, iar rezumatul spune 4 passed.
Ieșire: program Python complet
import pytest
def add(a, b):
return a + b
@pytest.mark.parametrize("a, b, want", [
(1, 1, 2),
(5, -3, 2),
(-2, -4, -6),
(0, 0, 0),
], ids=["one_plus_one", "positive_and_negative", "both_negative", "zeros"])
def test_add(a, b, want):
assert add(a, b) == want
Rularea unui singur caz
Cazurile pot fi selectate din linia de comandă cu -k, care caută potriviri în numele testului și în id-ul cazului:
pytest -v -k "both_negative"
Rulează doar cazul potrivit; celelalte sunt deselected (deselectate) și nici nu pornesc. Acest lucru este ideal când repari un caz stricat: rulezi din nou doar acel caz până devine verde, apoi rulezi totul din nou.
Filtrare cu -k
Același fișier ca mai sus, rulat cu -k "both_negative". Se execută doar unul dintre cele patru cazuri — antetul numără 3 deselected și 1 selected, iar rezumatul spune 1 passed, 3 deselected.
Ieșire: program Python complet
import pytest
def add(a, b):
return a + b
@pytest.mark.parametrize("a, b, want", [
(1, 1, 2),
(5, -3, 2),
(-2, -4, -6),
(0, 0, 0),
], ids=["one_plus_one", "positive_and_negative", "both_negative", "zeros"])
def test_add(a, b, want):
assert add(a, b) == want