Python 夹具试验夹具
我目前正在为一个中等大小的库(约300个文件)编写测试。 此库中的许多类共享使用pytest编码的相同测试方案: 文件测试\u针对\u类\u a.py:Python 夹具试验夹具,python,pytest,Python,Pytest,我目前正在为一个中等大小的库(约300个文件)编写测试。 此库中的许多类共享使用pytest编码的相同测试方案: 文件测试\u针对\u类\u a.py: import pytest @pytest.fixture() def setup_resource_1(): ... @pytest.fixture() def setup_resource_2(): ... @pytest.fixture() def setup_class_a(setup_resource_1, se
import pytest
@pytest.fixture()
def setup_resource_1():
...
@pytest.fixture()
def setup_resource_2():
...
@pytest.fixture()
def setup_class_a(setup_resource_1, setup_resource_2):
...
def test_1_for_class_a(setup_class_a):
...
def test_2_for_class_a(setup_class_a):
...
b类、c类等也有类似的文件。。。唯一的区别是设置资源1和设置资源2的内容
现在,我想重新使用test_for_class_a.py、test_for_class_b.py和test_for_class_c.py中定义的fixture setup_class_a、setup_class_b、setup_class_c.py来运行测试
在文件test_all_class.py中,此操作有效,但每次测试仅限于一个夹具:
from test_for_class_a import *
@pytest.mark.usefixtures('setup_class_a') # Fixture was defined in test_for_class_a.py
def test_some_things_on_class_a(request)
...
但我正在寻找一种更一般的方法:
from test_for_class_a import *
from test_for_class_b import * # I can make sure I have no collision here
from test_for_class_c import * # I can make sure I have no collision here
==> @generate_test_for_fixture('setup_class_a', 'setup_class_b', 'setup_class_c')
def test_some_things_on_all_classes(request)
...
有没有办法做到这一点?
我一直在关注工厂的工厂和抽象的pytest工厂,但我正在努力研究pytest定义夹具的方式。
有什么方法可以解决这个问题吗?我发现的一个解决方案是滥用测试用例,如下所示:
from test_for_class_a import *
from test_for_class_b import *
from test_for_class_c import *
list_of_all_fixtures = []
# This will force pytest to generate all sub-fixture for class a
@pytest.mark.usefixtures(setup_class_a)
def test_register_class_a_fixtures(setup_class_a):
list_of_fixtures.append(setup_class_a)
# This will force pytest to generate all sub-fixture for class b
@pytest.mark.usefixtures(setup_class_b)
def test_register_class_b_fixtures(setup_class_b):
list_of_fixtures.append(setup_class_b)
# This will force pytest to generate all sub-fixture for class c
@pytest.mark.usefixtures(setup_class_c)
def test_register_class_b_fixtures(setup_class_c):
list_of_fixtures.append(setup_class_c)
# This is the real test to apply on all fixtures
def test_all_fixtures():
for my_fixture in list_of_all_fixtures:
# do something with my_fixture
这隐式地依赖于这样一个事实,即所有test_all_fixture都是在所有test_register_类*之后执行的。它显然很脏,但它能工作…我们在工作中遇到了同样的问题,我希望每个案例只写一次夹具。所以我写了插件
pytest data
,就是这样做的。例如:
@pytest.fixture
def resource(request):
resource_data = get_data(reqeust, 'resource_data', {'some': 'data', 'foo': 'foo'})
return Resource(resource_data)
@use_data(resource_data={'foo': 'bar'})
def test_1_for_class_a(resource):
...
@use_data(resource_data={'foo': 'baz'})
def test_2_for_class_a(resource):
...
最棒的是,您只需编写一次带有一些默认值的fixture。当您只需要该装置/资源,而不关心具体的设置时,您只需要使用它。当您需要测试某个特定属性时,比如说检查该资源是否也可以处理100个字符长的值,您可以通过use\u data
decorator传递它,而不是编写另一个fixture
这样你就不必关心冲突,因为一切都只会发生一次。然后,您可以对所有装置使用conftest.py
,而无需在测试模块中导入。例如,我们分离了所有装置的深层模块,所有装置都包含在topconftest.py
中
插件
pytest数据的文档
:我认为,只有pytest\u generate\u test()
()才能给你这样的定制能力:
def pytest\u generate\u测试(metafunc):
如果metafunc.funcargnames中的“db”:
metafunc.addcall(param=“d1”)
metafunc.addcall(param=“d2”)
编辑:Ooops,回答了一个问题:我有比python更老的经验