有没有办法在pytest-bdd "When"步骤中使用pytest.rais?



我想定义一个场景如下:

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"步骤的所有其他用途。

我不确定我是否正确理解了你的问题,但你不是在努力实现这样的目标吗?

  1. 在每个When步骤之前,我们检查下一个Then步骤是否包含"is raised"

  2. 如果是,我们将此When步骤标记为"预计失败"。

  3. 在需要的When步骤执行时,我们检查相应的标志并使用pytest.raises方法来处理它。

对于前两个步骤,我使用pytest_bdd_before_step钩子和request夹具。第三,我只是在测试模块中定义了一些函数handle_step。当然你应该把它搬到别的地方去。这个函数需要step(它只是你代码中的一些定义函数)和request.node.step.expect_failure来决定是否使用pytest.raises

作为一个选项,您可以使用可调用的fixture(请求requestfixture)来存储此函数,并避免在此类关键字中使用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

最新更新