अद्यतन: चूंकि यह इस प्रश्न का स्वीकृत उत्तर है और फिर भी कभी-कभी उठ जाता है, मुझे एक अद्यतन जोड़ना चाहिए। यद्यपि मेरा मूल उत्तर (नीचे) पाइस्टेस्ट के पुराने संस्करणों में ऐसा करने का एकमात्र तरीका था क्योंकि अन्य ने पहले से ही उल्लेख किया है कि अब जुड़नार के अप्रत्यक्ष पैराट्रिएजेशन का समर्थन करता है। उदाहरण के लिए आप ऐसा कुछ कर सकते हैं (@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 ...
और इसी तरह।
ओपी का प्रयास समाधान सही दिशा में आगे बढ़ रहा था, और जैसा कि @ 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
विशेषता को बनाए जाने के बाद अद्यतन किया जा सके, व्यक्तिगत परीक्षणों के लिए व्यवहार को मोड़ने के लिए।