8

我有一些固定装置在conftest.py实际测试功能中运行良好。但是,我想pytest_generate_tests()根据其中一些夹具中的数据参数化一些测试。

我想做什么(简化):

-- conftest.py --
# my fixture returns a list of device names.
@pytest.fixture(scope="module")
def device_list(something):
    return ['dev1', 'dev2', 'dev3', 'test']

-- test001.py --
# generate tests using the device_list fixture I defined above.
def pytest_generate_tests(metafunc):
    metafunc.parametrize('devices', itertools.chain(device_list), ids=repr)

# A test that is parametrized by the above function.
def test_do_stuff(devices):
    assert "dev" in devices

# Output should/would be:
dev1: pass
dev2: pass
dev3: pass
test: FAIL

当然,我遇到的问题是在 pytest_generate_tests() 中,它抱怨 device_list 未定义。如果我尝试将其传递给 pytest_generate_tests(metafunc, device_list),则会出现错误。

E   pluggy.callers.HookCallError: hook call must provide argument 'device_list'

我想这样做的原因是我在不同文件中的一堆不同测试中使用了“device_list”列表,我想使用 pytest_generate_tests() 使用相同的列表对测试进行参数化。

这是不可能的吗?如果我必须在该函数中复制我的固定装置,那么使用 pytest_generate_tests() 有什么意义?

4

3 回答 3

2

从我多年来收集的资料来看,fixture 与 pytest 的后期收集阶段非常紧密地耦合在一起。我已经尝试过很多次做类似的事情,但从来没有真正成功过。

相反,您可以创建一个函数来执行您的夹具将执行的操作,并在 generate_tests 钩子中调用它。然后,如果您仍然需要它作为固定装置,请再次调用它(或保存结果或其他)。

于 2019-12-12T20:08:59.310 回答
0

经历了同样的问题,同时得到了这篇文章,它以某种方式提供了一种解决方法。看看救援标题的 Hooks下的底部,你会得到这个:

def pytest_generate_tests(metafunc):
""" This allows us to load tests from external files by
parametrizing tests with each test case found in a data_X
file """
for fixture in metafunc.fixturenames:
    if fixture.startswith('data_'):
        # Load associated test data
        tests = load_tests(fixture)
        metafunc.parametrize(fixture, tests)

看,这里它是通过调用前缀为'data_'的fixture来加载数据。

于 2021-03-08T13:06:14.643 回答
0
@pytest.fixture(scope="module", autouse=True)
def device_list(something):
    device_list = ['dev1', 'dev2', 'dev3', 'test']
    return device_list

通过autouse=True在 pytest 夹具装饰器中使用,您可以确保可以pytest_generate_tests访问device_list.

于 2021-07-12T21:09:47.377 回答