Python 将参数传递给fixture函数
我正在使用py.test测试python类MyTester中包装的一些DLL代码。 为了进行验证,我需要在测试期间记录一些测试数据,然后进行更多处理。因为我有很多测试题。。。我希望在大多数测试中重用tester对象创建(MyTester实例)的文件 由于tester对象是获取DLL变量和函数引用的对象,我需要为每个测试文件将DLL变量列表传递给tester对象(要记录的变量与测试文件相同)。 清单的内容应用于记录规定的数据 我的想法是这样做:Python 将参数传递给fixture函数,python,fixtures,pytest,Python,Fixtures,Pytest,我正在使用py.test测试python类MyTester中包装的一些DLL代码。 为了进行验证,我需要在测试期间记录一些测试数据,然后进行更多处理。因为我有很多测试题。。。我希望在大多数测试中重用tester对象创建(MyTester实例)的文件 由于tester对象是获取DLL变量和函数引用的对象,我需要为每个测试文件将DLL变量列表传递给tester对象(要记录的变量与测试文件相同)。 清单的内容应用于记录规定的数据 我的想法是这样做: import pytest class MyTes
import pytest
class MyTester():
def __init__(self, arg = ["var0", "var1"]):
self.arg = arg
# self.use_arg_to_init_logging_part()
def dothis(self):
print "this"
def dothat(self):
print "that"
# located in conftest.py (because other test will reuse it)
@pytest.fixture()
def tester(request):
""" create tester object """
# how to use the list below for arg?
_tester = MyTester()
return _tester
# located in test_...py
# @pytest.mark.usefixtures("tester")
class TestIt():
# def __init__(self):
# self.args_for_tester = ["var1", "var2"]
# # how to pass this list to the tester fixture?
def test_tc1(self, tester):
tester.dothis()
assert 0 # for demo purpose
def test_tc2(self, tester):
tester.dothat()
assert 0 # for demo purpose
有没有可能做到这一点,或者有没有更优雅的方式
通常,我可以使用某种设置函数(xUnit风格)对每个测试方法进行设置。但我想获得某种重用。有人知道这在固定装置上是否可行吗
我知道我可以做这样的事情:(从文件中)
但是我需要直接在测试模块中进行参数化。
是否可以从测试模块访问夹具的params属性?您可以从夹具功能访问请求的模块/类/功能(因此也可以从测试仪类访问),请参阅。因此,您可以在类或模块上声明一些参数,并且测试设备可以获取这些参数。更新:由于这是这个问题的公认答案,而且有时仍然会被更新,因此我应该添加一个更新。虽然我最初的答案(如下)是在pytest的旧版本中实现这一点的唯一方法,因为pytest现在支持夹具的间接参数化。例如,您可以这样做(通过@imiric): 然而,尽管这种形式的间接参数化是明确的,如@Yukihiko Shinoda,它现在支持一种形式的隐式间接参数化(尽管我在官方文件中找不到任何明显的参考): 我不知道这个表单的确切语义是什么,但似乎
pytest.mark.parametize
认识到,尽管test\u tc1
方法不接受名为tester\u arg
的参数,但它所使用的tester
夹具会接受,因此,它通过tester
fixture传递参数化参数
我有一个类似的问题——我有一个名为
test\u package
的fixture,后来我希望在特定测试中运行该fixture时能够向该fixture传递一个可选参数。例如:
@pytest.fixture()
def test_package(request, version='1.0'):
...
request.addfinalizer(fin)
...
return package
(出于这些目的,夹具的功能或返回的包的对象类型无关紧要)
然后,希望在测试函数中以某种方式使用这个fixture,这样我还可以为该fixture指定version
参数,以用于该测试。这在目前是不可能的,尽管这可能是一个很好的特性
同时,很容易让我的fixture返回一个函数,该函数完成fixture之前所做的所有工作,但允许我指定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.\uuuu init\uuuu
可以存储对请求的引用,如:
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
属性,以调整单个测试的行为。py.test via实际上支持这一点
在您的情况下,您应该:
@pytest.fixture
def tester(request):
"""Create tester object"""
return MyTester(request.param)
class TestIt:
@pytest.mark.parametrize('tester', [['var1', 'var2']], indirect=True)
def test_tc1(self, tester):
tester.dothis()
assert 1
稍微改进一下:解决这个问题的另一个优雅的方法是创建“参数装置”。我个人更喜欢它,而不是pytest
的indirect
特性。此功能可从获得,最初的想法是由提出的
请注意,pytest案例
还提供了@fixture
,允许您直接在设备上使用参数化标记,而不必使用@pytest.fixture(params=…)
和@使用_cases
参数化_,允许您从“case functions”中获取参数,这些“case functions”可以分组在一个类中,甚至单独的模块中。有关详细信息,请参阅。顺便说一句,我是作者;) 我找不到任何文档,但是,它似乎在最新版本的pytest中工作
@pytest.fixture
def测试仪(测试仪参数):
“”“创建测试程序对象”“”
返回MyTester(测试仪参数)
类别测试:
@pytest.mark.parametize('tester_arg',[['var1','var2']]))
def测试_tc1(自身,测试仪):
测试员
断言1
我制作了一个有趣的装饰器,允许编写如下装置:
import pytest
class MyTester():
def __init__(self, arg = ["var0", "var1"]):
self.arg = arg
# self.use_arg_to_init_logging_part()
def dothis(self):
print "this"
def dothat(self):
print "that"
# located in conftest.py (because other test will reuse it)
@pytest.fixture()
def tester(request):
""" create tester object """
# how to use the list below for arg?
_tester = MyTester()
return _tester
# located in test_...py
# @pytest.mark.usefixtures("tester")
class TestIt():
# def __init__(self):
# self.args_for_tester = ["var1", "var2"]
# # how to pass this list to the tester fixture?
def test_tc1(self, tester):
tester.dothis()
assert 0 # for demo purpose
def test_tc2(self, tester):
tester.dothat()
assert 0 # for demo purpose
@fixture\u获取参数
def狗(请求,/,姓名,年龄=69):
返回f“{name}年龄为{age}的狗”
在这里,/
左侧有其他装置,右侧有使用以下装置提供的参数:
@dog.arguments("Buddy", age=7)
def test_with_dog(dog):
assert dog == "Buddy the dog aged 7"
这与函数参数的工作方式相同。如果不提供age
参数,将使用默认的69
。如果不提供名称
,或省略dog.arguments
装饰符,则会得到常规的类型错误:dog()缺少1个必需的位置参数:“name”
。如果有另一个fixture接受参数name
,则它与此fixture不冲突
还支持异步装置
此外,这为您提供了一个很好的设置计划:
$ pytest test_dogs_and_owners.py --setup-plan
SETUP F dog['Buddy', age=7]
...
SETUP F dog['Champion']
SETUP F owner (fixtures used: dog)['John Travolta']
一个完整的例子:
从插件导入夹具获取参数
@fixture_taking_参数
def狗(请求,/,姓名,年龄=69):
返回f“{name}年龄为{age}的狗”
@fixture_taking_参数
def所有者(请求,狗,/,name=“John Doe”):
产生f{name},owne
@pytest.fixture()
def tester(request):
""" create tester object """
# how to use the list below for arg?
_tester = MyTester(request)
return _tester
@pytest.fixture
def tester(request):
"""Create tester object"""
return MyTester(request.param)
class TestIt:
@pytest.mark.parametrize('tester', [['var1', 'var2']], indirect=True)
def test_tc1(self, tester):
tester.dothis()
assert 1
import pytest
from pytest_cases import param_fixture
# create a single parameter fixture
var = param_fixture("var", [['var1', 'var2']], ids=str)
@pytest.fixture
def tester(var):
"""Create tester object"""
return MyTester(var)
class TestIt:
def test_tc1(self, tester):
tester.dothis()
assert 1
from pytest_cases import fixture, parametrize
@fixture
@parametrize("var", [['var1', 'var2']], ids=str)
def tester(var):
"""Create tester object"""
return MyTester(var)
@dog.arguments("Buddy", age=7)
def test_with_dog(dog):
assert dog == "Buddy the dog aged 7"
$ pytest test_dogs_and_owners.py --setup-plan
SETUP F dog['Buddy', age=7]
...
SETUP F dog['Champion']
SETUP F owner (fixtures used: dog)['John Travolta']