我有一个带有昂贵的工具的测试套件(它在集群中增加了一堆容器),所以我想为它使用一个会话范围的夹具。但是,它可以在多个轴上进行配置,不同的测试子集需要测试配置空间的不同子集。
下面是我试图做的最起码的演示。默认情况下,测试需要测试组合x=1、y=10和x=2、y=10,但是test_foo.py中的测试需要测试x=3,y=10需要覆盖x
夹具:
conftest.py:
import pytest
@pytest.fixture(scope="session", params=[1, 2])
def x(request):
return request.param
@pytest.fixture(scope="session", params=[10])
def y(request):
return request.param
@pytest.fixture(scope="session")
def expensive(x, y):
return f"expensive[{x}, {y}]"
test_bar.py:
def test_bar(expensive):
assert expensive in {"expensive[1, 10]", "expensive[2, 10]"}
test_foo.py:
import pytest
@pytest.fixture(scope="session", params=[3])
def x(request):
return request.param
def test_foo(expensive):
assert expensive in {"expensive[3, 10]"}
当我运行这个程序时,我得到以下信息:
test_bar.py::test_bar[1-10] PASSED [ 33%]
test_foo.py::test_foo[3-10] FAILED [ 66%]
test_bar.py::test_bar[2-10] PASSED [100%]
=================================== FAILURES ===================================
________________________________ test_foo[3-10] ________________________________
expensive = 'expensive[1, 10]'
def test_foo(expensive):
> assert expensive in {"expensive[3, 10]"}
E AssertionError: assert 'expensive[1, 10]' in {'expensive[3, 10]'}
它似乎重用了来自test_bar的1-10夹具,用于test_foo的3-10测试.这是预期的(某种类型的参数列表中的位置匹配,而不是值),还是pytest中的bug?有什么办法能让我做我想做的事吗?
顺便说一句,如果我让x
在test_foo.py
中非参数化(只是返回一个硬编码的3),它也会失败,但方式略有不同:它先运行两个test_bar
测试,然后再使用第二个夹具进行test_foo
测试。
发布于 2022-06-14 19:23:18
这里的问题是,expansive
夹具在会话范围内,参数只读取一次。
解决方法是将expansive
移动到模块范围,以便对每个模块进行评估。这是可行的,但它将评估每个测试模块的夹具,即使其中几个模块使用相同的参数。如果您有几个使用相同参数的测试模块,则可以使用两个具有不同作用域的独立夹具,然后移出通用代码,例如:
import pytest
...
def do_expansive_stuff(a, b): # a and b are normal arguments, not fixtures
# setup containers with parameters a, b...
return f"expensive[{a}, {b}]"
@pytest.fixture(scope="session")
def expensive(x, y):
yield do_expansive_stuff(x, y)
@pytest.fixture(scope="module")
def expensive_module(x, y):
yield do_expansive_stuff(x, y)
您可以在expensive_module
中使用test_foo
。当然,这是假定必须对每个参数集分别进行扩展设置。当然,这种方法的缺点是必须使用不同的名称。
如果有人能想出一个更干净的方法.
https://stackoverflow.com/questions/72617833
复制相似问题