我想使用非常慢的 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()
从迄今为止我不成功的尝试中我了解到:
可能有一个非常简单的解决方案。
答案 0 :(得分:5)
pytest fixtures 是适合您的解决方案。夹具的生命周期可能是单个测试、类、模块或整个测试会话。
<块引用>夹具管理从简单的单元扩展到复杂的功能测试,允许根据配置和组件选项参数化夹具和测试,或者跨功能、类、模块或整个测试会话范围重用夹具。
根据 Fixture availability paragraph,您需要在类或模块级别定义功能。
考虑使用模块范围的(注意,初始化只启动一次):
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
现在,如果您需要它是断言安全的(即使测试失败也释放资源),请考虑以上下文管理器的方式创建 heavy_context
(更多详细信息请参见:Fixture, Running multiple assert statements safely):>
import pytest
@pytest.fixture(scope="module")
def heavy_context():
print("Slow context initialized")
obj = ["I'm heavy"]
# It is mandatory to put deinitialiation into "finally" scope
# otherwise in case of exception it won't be executed
try:
yield obj[0]
finally:
print("Slow context released")
def test_1(heavy_context):
# Pay attention, that in fact heavy_context now
# is what we initialized as 'obj' in heavy_context
# function.
print(f"\nUse of heavy context: {heavy_context}")
def test_2(heavy_context):
print(f"\nUse of heavy context: {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
答案 1 :(得分:1)
您是否可以在不再次初始化对象的情况下一个接一个地运行测试,例如:
@pytest.mark.parametrize("params", LIST_OF_RANDOMIZED_PARAMS)
def test_one(params):
state = very_slow_initialization(params)
assert state.fast_test()
assert state.another_fast_test()
或为组织使用单独的功能:
@pytest.mark.parametrize("params", LIST_OF_RANDOMIZED_PARAMS)
def test_main(params):
state = very_slow_initialization(params)
step_one(state)
step_two(state)
def step_one(state):
assert state.fast_test()
def step_two(state):
assert state.another_fast_test()
虽然它是一个测试脚本,但您仍然可以使用函数来组织您的代码。在具有单独功能的版本中,您甚至可以声明一个固定装置,以防其他测试中也可能需要该状态:
@pytest.fixture(scope="module", params=LIST_OF_RANDOMIZED_PARAMS)
def state(request):
return very_slow_initialization(request.param)
def test_main(state):
step_one(state)
step_two(state)
def step_one(state):
assert state.fast_test()
def step_two(state):
assert state.another_fast_test()
我希望我没有在这里做错,但它应该像这样工作。