はじめに
pytestのfixtureは同じ条件でテストを繰り返したいときに非常に便利なツールです。いろいろな条件に共通するテストを書くために、fixtureをテストのパラメータにしたいと考えた時に、意外と情報がネットにまとまっていなかったので、ここに記載します。
ちなみに、fixtureをテストのパラメータにする方法については、公式ページ やGitHub で議論されているので、近い将来にもう少し簡単な方法が提供される可能性はあります。
やりたいこと
import pytest
@pytest.fixture
def fixture_a():
yield 1
@pytest.fixture
def fixture_b():
yield 2
@pytest.fixture
def fixture_c():
yield 3
@pytest.mark.parametrize("expected, generated", [
(1, fixture_a),
(2, fixture_b),
(5, fixture_c),
])
def test_fail(expected, generated):
assert expected == generated
ただし、これはうまくいかない。
代替策
デコレータpytest.fixture
を使うことで、fixtureをまとめる。
test.py
# 他の関数のは上記と同じ
@pytest.fixture(params=['a', 'b', 'c'])
def context(request):
if request.param == 'a':
return (1, request.getfixturevalue('fixture_a'))
elif request.param == 'b':
return (2, request.getfixturevalue('fixture_b'))
elif request.param == 'c':
return (4, request.getfixturevalue('fixture_c'))
def test_fixture_parameterize(context):
expected, generated = context
assert expected == generated
$ pytest test.py
========================================= test session starts =========================================
platform linux2 -- Python 2.7.12, pytest-3.1.0, py-1.4.33, pluggy-0.4.0
rootdir: /home/koreyou/work/pytest_fixture_parameterize, inifile:
collected 3 items
test.py ..F
============================================== FAILURES ===============================================
____________________________________ test_fixture_parameterize[c] _____________________________________
context = (4, 3)
def test_fixture_parameterize(context):
expected, generated = context
> assert expected == generated
E assert 4 == 3
test.py:31: AssertionError
================================= 1 failed, 2 passed in 0.02 seconds ==================================
期待どおり失敗する。