跳过行为步骤的实现

12 投票
3 回答
8625 浏览
提问于 2025-04-29 00:17

有没有办法让行为在步骤实现中跳过当前步骤呢?

就像这样:

@given("bla bla bla")
def step():
    skip_current_step()

我的需求是检查一下是否安装了某些额外的软件。如果没有安装,我希望整个场景都能被跳过。

暂无标签

3 个回答

3

这要看你想要什么效果。如果你想让behave跳过某一个特定的步骤,并且仅仅是这个步骤,那么从1.2.5版本开始,behave并没有提供这样的功能。你可以查看一下behave/model.py,会发现Step类里没有skipmark_skipped这两个方法。也就是说,没有其他的方式可以做到这一点。

如果你想让behave把这个步骤以及整个场景都标记为跳过,那这是可以的。如果你可以接受这种情况,那么Barry的回答其实就是在1.2.5之前你需要在behave中做的事情:使用before_feature来扫描场景,并在运行之前把它们标记为跳过。这样就能有效地把你的步骤标记为跳过。

正如m4tx的回答所示,从behave 1.2.5开始,你可以在步骤的实现函数中调用context.scenario.skip来跳过整个场景。不过,再次强调,这样会把整个场景都标记为跳过。确实,之前的步骤会执行并有可能失败,但当这个场景被统计为跳过时,所有的步骤(包括在调用context.scenario.skip之前可能已经通过的步骤)都会出现在跳过的步骤列表中。而且,调用context.scenario.skip之后的步骤将完全不会执行。

14

让我来改进一下@Barry的回答:

基本上,他提到的内容(也就是 scenario.mark_skipped())等同于:

scenario.skip(require_not_executed=True)

具体来说,mark_skipped() 的源代码长这样:

def mark_skipped(self):
    """Marks this scenario (and all its steps) as skipped.
    Note that this method can be called before the scenario is executed.
    """
    self.skip(require_not_executed=True)
    assert self.status == "skipped", "OOPS: scenario.status=%s" % self.status

skip() 是这样定义的:

def skip(self, reason=None, require_not_executed=False)

有几点需要注意:

  • require_not_executed=True 的意思是,如果有任何步骤已经通过,那么这个场景就不能被跳过。也就是说,如果在第二步或之后的步骤中调用 mark_skipped(),会抛出一个异常,并且会跳过后面的所有步骤,而不仅仅是跳过后面的步骤。
  • skip() 允许你提供一个跳过的理由,这个理由会被记录为 WARN

此外,scenario 对象可以通过 context.scenario 在上下文中使用(还有 context.feature)。

最后,给个简单的例子:

@given("test photos in upload directory")
def step_impl(context):
    if not connection_available():
        context.scenario.skip(reason='internet connection is unavailable')

结果:

Skipped: skipped
WARNING:behave:SKIP Scenario Retrieving uploaded photo details: internet connection is unavailable
5

我不太确定你是否可以在某个步骤内部跳过,但你可以在功能层面跳过整个场景:

def before_feature(context, feature):
    is_software_installed = some_foo_magic()

    if not is_software_installed:
        for scenario in feature.scenarios:
            if depends_on_software(scenario):
                scenario.mark_skipped()

Feature(功能)、Scenario(场景)和 ScenarioOutline(场景大纲)都有一个 mark_skipped() 方法。

撰写回答