更新:これはこの質問に対する受け入れられた回答であり、それでも時々賛成されるため、更新を追加する必要があります。私の最初の答え(以下)は、pytestの古いバージョンでこれを行う唯一の方法でしたが、他の人が指摘したように、 pytestはフィクスチャの間接的なパラメーター化をサポートするようになりました。たとえば、次のようなことができます (@imiric 経由):
# test_parameterized_fixture.py
import pytest
class MyTester:
def __init__(self, x):
self.x = x
def dothis(self):
assert self.x
@pytest.fixture
def tester(request):
"""Create tester object"""
return MyTester(request.param)
class TestIt:
@pytest.mark.parametrize('tester', [True, False], indirect=['tester'])
def test_tc1(self, tester):
tester.dothis()
assert 1
$ pytest -v test_parameterized_fixture.py
================================================================================= test session starts =================================================================================
platform cygwin -- Python 3.6.8, pytest-5.3.1, py-1.8.0, pluggy-0.13.1 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: .
collected 2 items
test_parameterized_fixture.py::TestIt::test_tc1[True] PASSED [ 50%]
test_parameterized_fixture.py::TestIt::test_tc1[False] FAILED
ただし、この形式の間接パラメーター化は明示的ですが、@ Yukihiko Shinoda が指摘するように、暗黙的な間接パラメーター化の形式をサポートするようになりました (ただし、公式ドキュメントでこれに関する明確な参照は見つかりませんでした)。
# test_parameterized_fixture2.py
import pytest
class MyTester:
def __init__(self, x):
self.x = x
def dothis(self):
assert self.x
@pytest.fixture
def tester(tester_arg):
"""Create tester object"""
return MyTester(tester_arg)
class TestIt:
@pytest.mark.parametrize('tester_arg', [True, False])
def test_tc1(self, tester):
tester.dothis()
assert 1
$ pytest -v test_parameterized_fixture2.py
================================================================================= test session starts =================================================================================
platform cygwin -- Python 3.6.8, pytest-5.3.1, py-1.8.0, pluggy-0.13.1 -- /usr/bin/python3
cachedir: .pytest_cache
rootdir: .
collected 2 items
test_parameterized_fixture2.py::TestIt::test_tc1[True] PASSED [ 50%]
test_parameterized_fixture2.py::TestIt::test_tc1[False] FAILED
この形式のセマンティクスが正確にはわかりませんが、メソッドは という名前の引数を取らないが、使用しているフィクスチャはそうするため、パラメータ化された引数をフィクスチャを介して渡すことをpytest.mark.parametrize
認識しているようです。test_tc1
tester_arg
tester
tester
私は同様の問題を抱えていました。私は というフィクスチャを持っていて、test_package
後で特定のテストで実行するときにオプションの引数をそのフィクスチャに渡せるようにしたいと考えました。例えば:
@pytest.fixture()
def test_package(request, version='1.0'):
...
request.addfinalizer(fin)
...
return package
(これらの目的では、フィクスチャが何をするか、または返されるオブジェクトのタイプは重要ではありませんpackage
)。
version
その場合、そのテストで使用するフィクスチャへの引数も指定できるように、テスト関数でこのフィクスチャを使用することが望ましいでしょう。素晴らしい機能になるかもしれませんが、これは現在不可能です。
それまでの間、フィクスチャが以前に実行したすべての作業を実行する関数を単純に返すようにするのは簡単でしたが、version
引数を指定できます。
@pytest.fixture()
def test_package(request):
def make_test_package(version='1.0'):
...
request.addfinalizer(fin)
...
return test_package
return make_test_package
これで、次のようなテスト関数でこれを使用できます。
def test_install_package(test_package):
package = test_package(version='1.1')
...
assert ...
等々。
OPが試みた解決策は正しい方向に向かっており、@ hpk42の回答が示唆するMyTester.__init__
ように、次のようなリクエストへの参照を保存することができます:
class MyTester(object):
def __init__(self, request, arg=["var0", "var1"]):
self.request = request
self.arg = arg
# self.use_arg_to_init_logging_part()
def dothis(self):
print "this"
def dothat(self):
print "that"
次に、これを使用して次のようなフィクスチャを実装します。
@pytest.fixture()
def tester(request):
""" create tester object """
# how to use the list below for arg?
_tester = MyTester(request)
return _tester
必要に応じて、個々のテストの動作を微調整するために、作成後にMyTester
その属性を更新できるように、クラスを少し再構築することができます。.args