为什么pytest_generate_tests钩子会出现“找不到fixture”的错误,而它明明定义了fixture?
我想通过pytest_generate_tests来使用外部数据(参数)实现以下功能。这个例子可以正常工作:
@pytest.mark.parametrize('case', [1,2,3,4])
def test_regression(case):
print case
assert True
假设我通过命令行参数获取测试数据。所以,我创建了一个conftest.py文件,添加了一个选项--data
,添加了一个fixture叫data
,并且添加了pytest_generate_tests
这个钩子。请注意,如果我不声明data
这个fixture,这个功能就无法正常工作(但在这个例子中没有fixture的声明):http://pytest.org/latest/example/parametrize.html#generating-parameters-combinations-depending-on-command-line
import pytest
def pytest_addoption(parser):
parser.addoption('--data', action='store', default='', help='Specify testing data')
@pytest.fixture
def data(request):
return request.config.getoption('--data')
def pytest_generate_tests(metafunc):
if 'data' in metafunc.funcargnames:
# imagine data.cases = [1,2,3,4,5]
metafunc.parametrize('case', [1,2,3,4,5])
例如,我有一个参数data,它包含了一些测试数据和测试用例。所以,我在conftest.py中这样定义:
# conftest.py
import pytest
def pytest_addoption(parser):
parser.addoption('--data', action='store', default='', help='Specify testing data')
@pytest.fixture
def data(request):
return request.config.getoption('--data')
def pytest_generate_tests(metafunc):
if 'data' in metafunc.fixturenames:
# lets imagine data.cases = [1,2,3,4,5]
metafunc.parametrize('case', [1,2,3,4,5])
# test.py (just removed @pytest.mark.parametrize line)
def test_regression(case):
print case
assert True
上面的例子会报错:找不到fixture 'case'。但是如果我把case
换成data
,它就能正常工作:
# conftest.py
import pytest
def pytest_addoption(parser):
parser.addoption('--data', action='store', default='', help='Specify testing data')
@pytest.fixture
def data(request):
return request.config.getoption('--data')
def pytest_generate_tests(metafunc):
if 'data' in metafunc.fixturenames:
# lets imagine data.cases = [1,2,3,4,5]
metafunc.parametrize('data', [1,2,3,4,5])
# test.py (just removed @pytest.mark.parametrize line)
def test_regression(data):
print case
assert True
但我需要一个名为case
的测试参数。我哪里做错了呢?
1 个回答
5
我今天遇到了差不多一样的问题:
我不能告诉你具体的根本原因,但问题似乎是传给测试函数的参数应该是一个“固定装置”(fixture)。所以如果你用的是 data
,那就没问题,因为它就像是一个固定装置。
但是如果你用的是 case
,就找不到对应的固定装置了。
我通过以下方式解决了这个问题:
def pytest_generate_tests(metafunc):
if 'func' in metafunc.fixturenames:
# do some stuff
metafunc.parametrize('func', all_combinations)
def test_function_prototypes(func):
assert func
这样做会出现 fixture 'func' not found
的错误。我通过添加以下几行代码解决了这个问题:
@pytest.fixture
def func(request):
return request.param # pass the param to the test function
我在文档中没有找到关于需要提供这个函数的说明。
我还注意到,重新取消注释这个固定装置后,代码仍然可以正常工作。我猜这可能和缓存有关……