Pytest:需要缓慢初始化的参数化测试
我想使用非常慢的init方法对类的随机参数进行测试。测试本身非常快,但需要一个耗时的初始化步骤。当然。我做这样的事情:
@pytest.mark.parametrize("params", LIST_OF_RANDOMIZED_PARAMS)
def test_one(params):
state = very_slow_initialization(params)
assert state.fast_test()
@pytest.mark.parametrize("params", LIST_OF_RANDOMIZED_PARAMS)
def test_two(params):
state = very_slow_initialization(params)
assert state.another_fast_test()
到目前为止,我从失败的尝试中了解到:
- 不支持使用参数化的 set_class(params) 方法初始化测试类
- 使用初始化类的夹具每次仍然调用慢初始化
- 我可以提前创建一个包含所有初始化状态的列表,但是它们需要大量内存。此外,有时我喜欢在一夜之间进行大量随机测试,然后在第二天早上停止它们。这一点我需要确切地知道我应该进行多少次测试,以便在此之前完成所有初始化。
- 如果可能的话,我更喜欢对第一个参数运行两个测试的解决方案,然后用第二个参数运行,依此类推。
可能有一个非常简单的解决方案。
回答
pytest fixtures是适合您的解决方案。夹具的生命周期可能是单个测试、类、模块或整个测试会话。
夹具管理从简单的单元扩展到复杂的功能测试,允许根据配置和组件选项对夹具和测试进行参数化,或者跨功能、类、模块或整个测试会话范围重用夹具。
每个灯具可用性段落,您需要在类或模块级别定义功能。
考虑使用模块范围的(注意,初始化只启动一次):
import pytest
@pytest.fixture(scope="module")
def heavy_context():
# Use your LIST_OF_RANDOMIZED_PARAMS randomized parameters here
# to initialize whatever you want.
print("Slow fixture initialized")
return ["I'm heavy"]
def test_1(heavy_context):
print(f"nUse of heavy context: {heavy_context[0]}")
def test_2(heavy_context):
print(f"nUse of heavy context: {heavy_context[0]}")
测试输出:
...
collecting ... collected 2 items
test_basic.py::test_1 Slow fixture initialized
PASSED [ 50%]
Use of heavy context: I'm heavy
test_basic.py::test_2 PASSED [100%]
Use of heavy context: I'm heavy
...
collecting ... collected 2 items
test_basic.py::test_1 Slow fixture initialized
PASSED [ 50%]
Use of heavy context: I'm heavy
test_basic.py::test_2 PASSED [100%]
Use of heavy context: I'm heavy
现在,如果您需要它是断言安全的(即使测试失败也释放资源),请考虑heavy_context以上下文管理器的方式创建(更多细节在这里:夹具,安全运行多个断言语句):
输出:
collecting ... collected 2 items
test_basic.py::test_1 Slow context initialized
PASSED [ 50%]
Use of heavy context: I'm heavy
test_basic.py::test_2 PASSED [100%]
Use of heavy context: I'm heavy
Slow context released
============================== 2 passed in 0.01s ===============================
Process finished with exit code 0