Python Pytest 解包夹具

fes*_*nuz 10 python testing pytest

我有一个夹具,可以在测试期间创建项目列表。我想要另一个夹具,它使用第一个夹具生成的值进行参数化。

示例代码

import random
import pytest

@pytest.fixture
def values():
    return [random.randint(0, 100) for _ in range(10)]


@pytest.fixture
def value(request):
    return request.param


@pytest.mark.parametrize("value", params=values):
def test_function(value):
    assert value > 0
Run Code Online (Sandbox Code Playgroud)

上面代码的问题在于它values是一个函数而不是一个列表。我做了很多挖掘,但没有找到任何方法来解压夹具来参数化另一个夹具。

我知道我可以通过values夹具并在测试中对其进行迭代,但这不是一个好的解决方案,因为我想查看哪些值导致测试失败。

我也对替代解决方案持开放态度,例如,如果可以从开始的测试运行子测试。

sma*_*rie 14

这似乎是对夹具概念及其与参数概念的区别的误解。

Pytest 有两个主要阶段:

  • 一个收集阶段,其目标是创建测试“节点”的列表运行。一个测试“节点”对应一个测试 id,表示每个参数一个值。在此阶段不执行夹具,仅读取装饰器标记(包含参数)。因此只有在装饰器中声明参数才能影响这个阶段。

  • 运行每个测试节点的执行阶段。在运行之前,所有尚未设置的必需灯具都已设置。因此,夹具功能在此阶段执行,并且仅在此阶段执行。他们的结果不能修改前一阶段已经完成的测试列表。

在您的示例中,您希望夹具设置(阶段 B)的结果更改要创建的测试列表(阶段 A):这在设计上是不可能的。你必须在pytest别的地方创建这个列表,例如初始化钩conftest.py或简单地在您的任何测试模块的共享变量,是指它在测试或夹具的参数。

另请参阅这个非常相似的问题:参数化测试取决于 pytest 中的参数化值

请注意,为了补充hoefling 对您的问题的评论,您现在可以在参数列表中使用参数化装置:我已在我的pytest-cases插件中添加了此功能以进行评估,以便我们最终可以建议将它合并到 pytest 中(请参阅此讨论,所以不要犹豫提供反馈!)。但不幸的是,由于上述根本原因,这并不能解决您在本文中描述的确切问题。