我用的是py。测试一些封装在python类MyTester中的DLL代码。
为了验证目的,我需要在测试期间记录一些测试数据,然后进行更多的处理。因为我有很多考试…我想为我的大多数测试重用测试器对象创建(MyTester的实例)。
由于测试对象是一个得到DLL的变量和函数的引用,我需要为每个测试文件传递一个DLL的变量列表到测试对象(要记录的变量对于test_…文件)。
列表的内容用于记录指定的数据。
我的想法是这样的:
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风格)为每个测试方法执行此操作。但我想获得某种重用。有人知道这在固定装置上是否可行吗?
我知道我可以这样做:(来自文档)
@pytest.fixture(scope="module", params=["merlinux.eu", "mail.python.org"])
但是我需要在测试模块中直接进行参数化。
是否可以从测试模块访问夹具的params属性?
另一种方法是使用请求对象访问定义测试函数的模块或类中定义的变量。
这样,如果您想为类/模块的所有测试函数传递相同的变量,就不必在测试类的每个函数上重用@pytest.mark. paramtrize()装饰器。
带有类变量的示例:
@pytest.fixture
def tester(request):
"""Create tester object"""
return MyTester(request.cls.tester_args)
class TestIt:
tester_args = ['var1', 'var2']
def test_tc1(self, tester):
tester.dothis()
def test_tc2(self, tester):
tester.dothat()
通过这种方式,test_tc1和test_tc2的测试器对象将使用test_args参数进行初始化。
你还可以使用:
请求。函数来访问test_tc1函数,
请求。实例来访问test类实例,
请求。模块来访问定义在test中的模块
等(参考请求文档)
您还可以使用闭包,这将为您提供更全面的参数命名和控制。它们比隐式参数化中使用的request参数更“显式”:
@pytest.fixture
def tester():
# Create a closure on the Tester object
def _tester(first_param, second_param):
# use the above params to mock and instantiate things
return MyTester(first_param, second_param)
# Pass this closure to the test
yield _tester
@pytest.mark.parametrize(['param_one', 'param_two'], [(1,2), (1000,2000)])
def test_tc1(tester, param_one, param_two):
# run the closure now with the desired params
my_tester = tester(param_one, param_two)
# assert code here
我使用它来构建可配置的fixture。
为了改进一点imiric的回答:另一种解决这个问题的优雅方法是创建“参数fixture”。与pytest的间接特性相比,我个人更喜欢它。这个特性可以从pytest_cases中获得,最初的想法是由Sup3rGeo提出的。
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
请注意,pytest-cases还提供了@fixture,允许您直接在fixture上使用参数化标记,而不必使用@pytest.fixture(params=…)
from pytest_cases import fixture, parametrize
@fixture
@parametrize("var", [['var1', 'var2']], ids=str)
def tester(var):
"""Create tester object"""
return MyTester(var)
@ paramtrize_with_cases允许您从“case函数”中获取参数,这些“case函数”可能被分组在一个类中,甚至是一个单独的模块中。详见医生。顺便说一下,我是作者;)