poprzedni temat | w górę | następny temat

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

  1. Dodaj nowe testy do przykładu powyżej, tak aby były jak najbardziej kompletne.

  2. Zainstaluj moduł pytest-cov i zbadaj za jego pomocą pokrycie kodu testami.

  3. Napisz testy do rozwiązania dowolnie wybranego zadania z tematu 7 lub 8.

poprzedni temat | w górę | następny temat