pytest でユニットテスト
pytestをインストールします。
$ uname -v
Darwin Kernel Version 14.0.0: Fri Sep 19 00:26:44 PDT 2014; root:xnu-2782.1.97~2/RELEASE_X86_64
$ python --version
Python 2.7.11 :: Anaconda custom (x86_64)
$ pip install pytest
テスト対象のコードを書きます。例として, 時刻を表す文字列 ‘%Y-%m-%dT%H:%M:%S’ の時刻の差分を計算する関数を書きます。
# -*- coding: utf-8 -*-
from datetime import datetime as dt
def diff(t1, t2):
t1 = dt.strptime(t1, '%Y-%m-%dT%H:%M:%S')
t2 = dt.strptime(t2, '%Y-%m-%dT%H:%M:%S')
return t1 - t2
次にテストコードを書きます。 二つ目の assert で失敗させるようにします。
# -*- coding: utf-8 -*-
import pytest
import diff as d
def test_diff():
expected = 365
actual = d.diff('2014-12-09T00:00:00', '2013-12-09T00:00:00').days
print('actual: %d, expected: %d' % (actual, expected))
assert actual == expected
expected = 12345
actual = d.diff('2014-12-09T00:00:00', '2013-12-09T00:00:00').seconds
print('actual: %d, expected: %d' % (actual, expected))
assert actual == expected
テストを実行します。レポートは簡潔な印象です。
$ pytest test_diff.py
======================================== test session starts ========================================
platform darwin -- Python 2.7.11, pytest-3.8.0, py-1.6.0, pluggy-0.7.1
rootdir: /xxxxx, inifile:
collected 1 item
test_diff.py F [100%]
============================================= FAILURES ==============================================
_____________________________________________ test_diff _____________________________________________
def test_diff():
expected = 365
actual = d.diff('2014-12-09T00:00:00', '2013-12-09T00:00:00').days
print('actual: %d, expected: %d' % (actual, expected))
assert actual == expected
expected = 12345
actual = d.diff('2014-12-09T00:00:00', '2013-12-09T00:00:00').seconds
print('actual: %d, expected: %d' % (actual, expected))
> assert actual == expected
E assert 0 == 12345
test_diff.py:15: AssertionError
--------------------------------------- Captured stdout call ----------------------------------------
actual: 365, expected: 365
actual: 0, expected: 12345
===================================== 1 failed in 0.36 seconds ======================================
pytest.mark.parametrize
続いて pytest.mark.parametrize によるテスト関数の引数のパラメータ化を試してみます。
@parametrize decorator にテスト関数の引数となる複数の tuple を定義します。 tuple の数だけテスト関数が呼ばれます。この機能を使うことでより宣言的なテストになります。
# -*- coding: utf-8 -*-
import pytest
import diff as d
@pytest.mark.parametrize("input,expected", [
(('2014-12-09T00:00:00', '2014-12-08T00:00:00'), 1),
(('2014-12-09T00:00:00', '2013-12-09T00:00:00'), 365),
(('2014-12-09T00:00:00', '2010-12-09T00:00:00'), 365*4+1)
])
def test_diff(input, expected):
actual = d.diff(input[0], input[1]).days
print('actual: %d, expected: %d' % (actual, expected))
assert actual == expected
テストを実行します。
$ pytest test_diff.py
======================================== test session starts ========================================
platform darwin -- Python 2.7.11, pytest-3.8.0, py-1.6.0, pluggy-0.7.1
rootdir: /xxxxx, inifile:
collected 3 items
test_diff.py ... [100%]
===================================== 3 passed in 0.10 seconds ======================================
virtualenv をアクティブ化している状態では pytest コマンドは使わず python -m オプションを使いモジュールとして pytest を指定する。
$ python -m pytest test_diff.py
======================================== test session starts ========================================
platform darwin -- Python 2.7.11, pytest-3.8.0, py-1.6.0, pluggy-0.7.1
rootdir: /xxxxx, inifile:
collected 3 items
test_diff.py ... [100%]
===================================== 3 passed in 0.18 seconds ======================================