Testy jednostkowe
Testy jednostkowe
będziemy pisać przy użyciu
pakietu pytest
.
# instalacja pakietu pytest ~ $ virtualenv env ~ $ source env/bin/activate (env)~ $ pip install pytest
Dla przykładu: chcemy napisać testy dla funkcji z zadania 2 z poprzedniego tematu.
# plik: liczby.py def num2text(n): return { 1: 'jeden', 2: 'dwa', 3: 'trzy', }.get(n)
Jak widać, powyższa funkcja nie jest kompletna, więc jest niezgodna ze specyfikacją. Testy, które napiszemy, powinny wskazać błędy w działaniu funkcji.
Stwórzmy więc plik test.py
:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | #!/usr/bin/env python # coding: utf-8 import liczby class Test(object): def test_answer_type(self): assert isinstance(liczby.num2text(1), basestring) def test_zero(self): assert liczby.num2text(0) == 'zero' def test_one(self): assert liczby.num2text(1) == 'jeden' def test_two(self): assert liczby.num2text(2) == 'dwa' |
Teraz możemy już uruchomić testy:
~ $ py.test test.py ============================= test session starts ====================== platform linux2 -- Python 2.7.9, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 rootdir: /home/user, inifile: collected 4 items test.py .F.. ================================== FAILURES ============================ _______________________________ Test.test_zero _________________________ self = <test.Test object at 0xb6d0704c> def test_zero(self): > assert liczby.num2text(0) == 'zero' E assert None == 'zero' E + where None = <function num2text at 0xb6d4faac>(0) E + where <function num2text at 0xb6d4faac> = liczby.num2text test.py:12: AssertionError ===================== 1 failed, 3 passed in 0.01 seconds ===============
Widać, że dla argumentu 0
funkcja zwróciła None
zamiast napisu 'zero'
.
Poprawmy funkcję num2text
.
def num2text(n): return { 0: 'zero', 1: 'jeden', 2: 'dwa', 3: 'trzy', }.get(n)
Gdy teraz uruchomimy testy, otrzymamy:
~ $ py.test test.py ============================= test session starts ====================== platform linux2 -- Python 2.7.9, pytest-2.9.1, py-1.4.31, pluggy-0.3.1 rootdir: /home/user, inifile: collected 4 items test.py .... ========================== 4 passed in 0.01 seconds ====================
Teraz już nasza funkcja przechodzi pomyślnie
wszystkie testy, mimo że ewidentnie nie powinna.
To znaczy, że testy są niekompletne i wymagają uzupełnienia. Poza testowaniem większych liczb, przetestujmy,
czy dla argumentów o typie innym, niż liczbowy,
zwracany jest wyjątek TypeError
.
def test_TypeError(self): with pytest.raises(TypeError): liczby.num2text([12])
Zadania
-
Dodaj nowe testy do przykładu powyżej, tak aby były jak najbardziej kompletne.
-
Zainstaluj moduł
pytest-cov
i zbadaj za jego pomocą pokrycie kodu testami. -
Napisz testy do rozwiązania dowolnie wybranego zadania z tematu 7 lub 8.