跳过行为步骤的实现
有没有办法让行为在步骤实现中跳过当前步骤呢?
就像这样:
@given("bla bla bla")
def step():
skip_current_step()
我的需求是检查一下是否安装了某些额外的软件。如果没有安装,我希望整个场景都能被跳过。
3 个回答
这要看你想要什么效果。如果你想让behave跳过某一个特定的步骤,并且仅仅是这个步骤,那么从1.2.5版本开始,behave并没有提供这样的功能。你可以查看一下behave/model.py
,会发现Step
类里没有skip
和mark_skipped
这两个方法。也就是说,没有其他的方式可以做到这一点。
如果你想让behave把这个步骤以及整个场景都标记为跳过,那这是可以的。如果你可以接受这种情况,那么Barry的回答其实就是在1.2.5之前你需要在behave中做的事情:使用before_feature
来扫描场景,并在运行之前把它们标记为跳过。这样就能有效地把你的步骤标记为跳过。
正如m4tx的回答所示,从behave 1.2.5开始,你可以在步骤的实现函数中调用context.scenario.skip
来跳过整个场景。不过,再次强调,这样会把整个场景都标记为跳过。确实,之前的步骤会执行并有可能失败,但当这个场景被统计为跳过时,所有的步骤(包括在调用context.scenario.skip
之前可能已经通过的步骤)都会出现在跳过的步骤列表中。而且,调用context.scenario.skip
之后的步骤将完全不会执行。
让我来改进一下@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
我不太确定你是否可以在某个步骤内部跳过,但你可以在功能层面跳过整个场景:
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()
方法。