আপডেট: যেহেতু এটি এই প্রশ্নের গৃহীত উত্তর এবং এখনও মাঝে মাঝে উত্সাহিত হয়, তাই আমার একটি আপডেট যুক্ত করা উচিত। যদিও (নীচে) আমার মূল উত্তর pytest পুরোনো সংস্করণে এই কাজ করার একমাত্র উপায় ছিল অন্যদের আছে লক্ষনীয় pytest এখন রাজধানী পরোক্ষ parametrization সমর্থন করে। উদাহরণস্বরূপ আপনি এই জাতীয় কিছু করতে পারেন (@ মিমিরিকের মাধ্যমে):
# 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
যাইহোক, যদিও অপ্রত্যক্ষ প্যারামিট্রাইজেশনের এই রূপটি স্পষ্ট, @ ইউকিহিকো শিনোদা উল্লেখ করেছেন যে এটি এখন অন্তর্নিহিত পরোক্ষ প্যারামিট্রাইজেশনের একটি রূপকে সমর্থন করে (যদিও আমি সরকারী ডক্সে এর কোনও সুস্পষ্ট উল্লেখ খুঁজে পাইনি):
# 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
, এবং পরে আমি নির্দিষ্ট পরীক্ষায় এটি চালানোর সময় সেই ফিক্সারের কাছে একটি alচ্ছিক যুক্তিটি পাস করতে সক্ষম হতে চাইতাম। উদাহরণ স্বরূপ:
@pytest.fixture()
def test_package(request, version='1.0'):
...
request.addfinalizer(fin)
...
return package
(এই উদ্দেশ্যগুলির জন্য এটি কোনও বিষয় নয় যে ফিক্সচারটি কী করে বা কী ধরণের জিনিস প্রত্যাবর্তিত হয় package
) is
এরপরে কোনওভাবে কোনও পরীক্ষার ফাংশনে এই ফিক্সিংটি এমনভাবে ব্যবহার করা বাঞ্ছনীয় হবে যে আমি 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 ...
ইত্যাদি।
ওপি'র চেষ্টা করা সমাধানটি সঠিক দিকে নিয়ে গিয়েছিল, এবং @ এইচপিপি 42 এর উত্তর অনুসারে, 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
এটি তৈরির পরে এর বৈশিষ্ট্যটি আপডেট করা যায়, স্বতন্ত্র পরীক্ষার জন্য আচরণটি টুইঙ্ক করতে।