Python Pytest 解包夹具 [英] Python Pytest unpack fixture

查看:48
本文介绍了Python Pytest 解包夹具的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I have a fixture that creates a list of items during tests. I want to have another fixture which is parametrized with values generated by the first one.

示例代码

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

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

The problem with above code is that values is a function and not a list. I did quite a lot of digging but didnt find any way to unpack fixture to parametrize another with it.

我知道我可以传递 values 固定装置并在测试中对其进行迭代,但这不是一个好的解决方案,因为我想查看哪些值导致测试失败.

Im aware that i can pass values fixture and iterate over it in tests, but that not a good solution since i want to see which values cause test to fail.

我也愿意接受替代解决方案,例如是否可以从开始的测试运行子测试.

Im also open to alternative solutions, for example if it is possible to run subtests from started test.

推荐答案

这似乎是对fixtures的概念及其与参数概念的区别的误解.

This seems like a misunderstanding of the concept of fixtures and its difference with the concept of parameters.

Pytest 有两个主要阶段:

Pytest has two major phases:

  • 收集阶段,目标是创建测试节点"列表.跑步.一个测试节点"对应一个测试ID,表示每个参数一个值.在此阶段不执行夹具,仅读取装饰器标记(包含参数).因此,只有在装饰器中声明的参数可以影响这个阶段.

  • a collection phase where the goal is to create a list of test "nodes" to run. One test "node" corresponds to one test id, and means one value for each parameter. In this phase fixtures are NOT executed, only the decorator marks (containing parameters) are read. Therefore only parameters declared in the decorators can influence this phase.

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

an execution phase where each test node is run. Before the run, all required fixtures that are not already setup are setup. Therefore the fixture functions are executed in this phase, and only in this phase. Their results can not modify the list of tests already done in the previous phase.

在您的示例中,您希望夹具设置(阶段 B)的结果更改要创建的测试列表(阶段 A):这在设计上是不可能的.您必须在其他地方创建此列表,例如在 pytest init 钩子中conftest.py 或简单地作为任何测试模块中的共享变量,并在测试或夹具的参数中引用它.

In your example, you want the result of a fixture setup (phase B) to change the list of tests to create (phase A): this is not possible by design. You have to create this list somewhere else, for example in a pytest init hook in a conftest.py or simply as a shared variable in any of your test modules, and refer to it in the parameters of your test or fixture.

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

See also this question that is quite similar: Parametrizing tests depending of also parametrized values in pytest

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

Note that to complement hoefling's comment to your question you can now use a parametrized fixture in a parameters list: I have added this feature in my pytest-cases plugin, for evaluation, so that we can eventually propose to merge it within pytest (see this discussion, so not hesitate to provide feedback!). But unfortunately this will not solve the precise problem you describe in this post, for the fundamental reason described above.

这篇关于Python Pytest 解包夹具的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆