Güncelleme: Bu sorunun cevabı kabul edildiğinden ve bazen hala olumlu oy verildiğinden, bir güncelleme eklemeliyim. Orijinal cevabım (aşağıda), başkalarının da belirttiği gibi, pytest'in eski sürümlerinde bunu yapmanın tek yolu olmasına rağmen , pytest artık armatürlerin dolaylı parametrizasyonunu desteklemektedir. Örneğin, bunun gibi bir şey yapabilirsiniz (@imiric aracılığıyla):
# 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
Ancak, dolaylı parametrelemesine bu formu @Yukihiko Shinoda olarak, açık olmasına rağmen işaret (ı resmi dokümanlar bu herhangi bariz bir başvuru bulamadık rağmen) şimdi örtülü dolaylı parametrelemesine biçimi destekler:
# 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
Bu formun anlamsallığının tam olarak ne olduğunu bilmiyorum, ancak görünen o pytest.mark.parametrize
ki, test_tc1
yöntem adlandırılmış bir argüman almasa da tester_arg
, kullandığı tester
fikstür, parametreleştirilmiş argümanı tester
fikstürden geçiriyor.
Benzer bir sorunum vardı - adlı bir fikstürüm var test_package
ve daha sonra belirli testlerde çalıştırırken o fikstüre isteğe bağlı bir argüman iletebilmek istedim. Örneğin:
@pytest.fixture()
def test_package(request, version='1.0'):
...
request.addfinalizer(fin)
...
return package
(Bu amaçlar için fikstürün ne yaptığı veya ne tür bir nesne olduğu önemli değildir package
).
O zaman bu armatürü bir şekilde bir test fonksiyonunda kullanmak, öyle ki ben de şunu belirtebilirim. version
o testte kullanmak için o fikstürün argümanını . Bu şu anda mümkün değil, ancak güzel bir özellik olabilir.
Bu arada , fikstürümün, fikstürün daha önce yaptığı tüm işi yapan, ancak argümanı belirtmeme izin veren bir işlevi döndürmesini sağlamak yeterince kolaydı version
:
@pytest.fixture()
def test_package(request):
def make_test_package(version='1.0'):
...
request.addfinalizer(fin)
...
return test_package
return make_test_package
Şimdi bunu test işlevimde şu şekilde kullanabilirim:
def test_install_package(test_package):
package = test_package(version='1.1')
...
assert ...
ve bunun gibi.
OP'nin denenen çözümü doğru yöne gidiyordu ve @ hpk42'nin cevabının önerdiği gibi, MyTester.__init__
sadece aşağıdaki gibi isteğe bir referans kaydedebilirdi:
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"
Ardından, fikstürü aşağıdaki gibi uygulamak için bunu kullanın:
@pytest.fixture()
def tester(request):
""" create tester object """
# how to use the list below for arg?
_tester = MyTester(request)
return _tester
İstenirse, MyTester
sınıf biraz yeniden yapılandırılabilir, böylece .args
özniteliği oluşturulduktan sonra bireysel testler için davranışı ince ayarlayacak şekilde güncellenebilir.