我目前正在为一个中等大小的库(大约300个文件)编写测试。这个库中的许多类共享相同的测试方案,这些方案是使用pytest编写的:
文件test_for_class_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, setup_resource_2):
...
def test_1_for_class_a(setup_class_a):
...
def test_2_for_class_a(setup_class_a):
...类似的文件也存在于class_b,class_c等。唯一的区别是setup_resource_1和setup_resource_2的内容不同。
现在我想重新使用在test_for_class_a.py、test_for_class_b.py和test_for_class_c.py中定义的fixtures setup_class_a、setup_class_b、setup_class_c来对它们运行测试。
在文件test_all_class.py中,这是可行的,但它被限制为每个测试只能有一个fixture:
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定义fixture的方式。有没有办法解决这个问题?
发布于 2016-06-02 03:10:37
我们在工作中遇到了同样的问题,我希望为每个案例只编写一次fixture。所以我写了一个插件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。当你只需要那个fixture/资源,而不关心具体的设置时,你可以直接使用它。当您需要测试某些特定属性时,假设要检查该资源是否也可以处理100个字符长值,您可以通过use_data装饰器传递它,而不是编写另一个fixture。
有了它,你就不必关心冲突了,因为所有的东西只会出现一次。然后,您可以对所有的fixture使用conftest.py,而无需在测试模块中导入。例如,我们分离了所有fixtures的深层模块,并且都包含在顶级conftest.py中。
插件pytest-data文档:http://horejsek.github.io/python-pytest-data/
发布于 2016-03-04 18:58:41
我发现的一个解决方案是滥用测试用例,如下所示:
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_class*之后执行的。它显然是相当脏,但它是有效的。
发布于 2021-03-14 07:08:22
我认为,只有pytest_generate_test() (example)才能提供这样的定制化能力:
def pytest_generate_tests(metafunc):
if 'db' in metafunc.funcargnames:
metafunc.addcall(param="d1")
metafunc.addcall(param="d2")编辑:哦,回答了比python更老的我有o.O经验的问题。
https://stackoverflow.com/questions/35777854
复制相似问题