在Python Behave中,如何在场景大纲之前运行特定步骤?

10

如标题所示,我希望在场景大纲之前运行某些特定的配置/环境设置步骤。我知道可以使用Background来为场景执行此操作,但Behave会将场景大纲拆分成多个场景,因此会为场景大纲中的每个输入运行背景。

这不是我想要的。由于某些原因,我无法提供我正在处理的代码,但我会编写一个示例功能文件。

Background: Power up module and connect
Given the module is powered up
And I have a valid USB connection

Scenario Outline: Example
    When I read the arduino
    Then I get some <'output'>

Example: Outputs
| 'output' |
| Hi       |
| No       |
| Yes      |

在这种情况下,Behave将会循环供电并检查每个输出的USB连接HiNoYes,导致三次循环和三次连接检查。

我希望的是Behave只循环供电并检查一次连接,然后运行所有三个测试。

我该如何做到这一点?

4个回答

7
您最好使用 before_feature 环境钩子,并将标签放在特性上和/或直接使用特性名称。

例如:

some.feature

@expensive_setup
Feature: some name
  description
  further description

  Background: some requirement of this test
    Given some setup condition that runs before each scenario
      And some other setup action

  Scenario: some scenario
      Given some condition
       When some action is taken
       Then some result is expected.

  Scenario: some other scenario
      Given some other condition
       When some action is taken
       Then some other result is expected.

steps/environment.py

def before_feature(context, feature):
    if 'expensive_setup' in feature.tags:
        context.execute_steps('''
            Given some setup condition that only runs once per feature
              And some other run once setup action
        ''')

替代步骤/环境.py

def before_feature(context, feature):
    if feature.name == 'some name':
        context.execute_steps('''
            Given some setup condition that only runs once per feature
              And some other run once setup action
        ''')

0

我遇到了完全相同的问题。 有一个 昂贵的 Background,应该只在每个Feature中执行一次。 实际上需要解决这个问题的是,在Scenario之间存储状态的能力。

我解决这个问题的方法是使用behave.runner.Context#_root,它在整个运行过程中都保持不变。我知道访问私有成员不是一个好习惯 - 我很乐意学习更清晰的方法。

# XXX.feature file
Background: Expensive setup
  Given we have performed our expensive setup

# steps/XXX.py file
@given("we have performed our expensive setup")
def step_impl(context: Context):    
    if not context._root.get('initialized', False):
        # expensive_operaion.do()
        context._root['initialized'] = True

我相信TomDotDom的答案是正确的方法。你_可以_这样做,但这就是steps/enviroment.py的目的,相比之下,这种方式感觉有点“hacky”。 - JGC

0

你不应该使用Background,而应该使用Scenario。如果你使用Background,那么Background步骤会重复执行。但是如果使用Scenario关键字,步骤就不会重复。

Feature: Example
Scenario: Scenario for Background
  When Login Step
  Then Verify Login Successfully
 Scenario Outline: Example
   When I read the arduino
    Then I get some <'output'>

Example: Outputs
| 'output' |
| Hi       |
| No       |
| Yes      |

0
你可以这样做:
  1. 在 Features 文件夹中创建 environment.py

  2. 在 environment.py 中添加代码:from behave import fixture

  3. 编写代码:

from behave import fixture

def before_feature(context, feature): print("在每个 Feature 运行前运行")

def after_feature(context, feature): print("在每个 Feature 运行后运行")

def before_scenario(context, scenario): print("在每个 Scenario 运行前运行")

def after_scenario(context, scenario): print("在每个 Scenario 运行后运行")

#现在运行你的测试用例,输出将是: 在每个 Feature 运行前运行 在每个 Scenario 运行前运行 在每个 Scenario 运行后运行 在每个 Feature 运行后运行


为什么你会在这个例子中提到 import fixture?而且,不,无论是 before_feature 还是 before_scenario 都不能控制 场景大纲,这正是 OP 所问的。 - Janos

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接