我想定义一个场景如下:
Scenario: An erroneous operation
Given some data
And some more data
When I perform an operation
Then an exception is raised
是否有一个好的方法来做到这一点,使when
步骤实际上没有调用,直到pytest.raises
上下文管理器可以为它构建?我可以使用一个可调用的fixture,但这会影响"I perform an operation"
步骤的所有其他用途。
我不确定我是否正确理解了你的问题,但你不是在努力实现这样的目标吗?
-
在每个
When
步骤之前,我们检查下一个Then
步骤是否包含"is raised"
。 -
如果是,我们将此
When
步骤标记为"预计失败"。 -
在需要的
When
步骤执行时,我们检查相应的标志并使用pytest.raises
方法来处理它。
对于前两个步骤,我使用pytest_bdd_before_step钩子和request
夹具。第三,我只是在测试模块中定义了一些函数handle_step
。当然你应该把它搬到别的地方去。这个函数需要step
(它只是你代码中的一些定义函数)和request.node.step.expect_failure
来决定是否使用pytest.raises
。
作为一个选项,您可以使用可调用的fixture(请求request
fixture)来存储此函数,并避免在此类关键字中使用request.node.step.expect_failure
。
还可以添加定义允许的异常等功能。
test_exception.py
import pytest
from pytest_bdd import then, when, scenario
@scenario("exc.feature", "Test expecting correct exception")
def test_1():
pass
def handle_step(step, expect_failure):
if expect_failure:
pytest.raises(Exception, step)
else:
step()
@when("I perform an operation")
def operation_calling_exception(request):
def step():
# some code that causes an exception
print(1 / 0)
handle_step(step, request.node.step.expect_failure)
@then('an exception is raised')
def ex_raised():
pass
exc.feature
Feature: Target fixture
Scenario: Test expecting correct exception
When I perform an operation
Then an exception is raised
conftest.py
def pytest_bdd_before_step(request, feature, scenario, step, step_func):
# set default `expect_failure` for step
step.expect_failure = False
# make step available from request fixture
request.node.step = step
# Only for `When` keywords
if step.keyword == "When":
# get current step position in scenario
step_position = scenario.steps.index(step)
# get following `Then` step
then_step = next((s for s in scenario.steps[step_position:] if s.keyword == "Then"), None)
if "is raised" in then_step.name:
step.expect_failure = True