行为:使用动态示例编写场景大纲 [英] Behave: Writing a Scenario Outline with dynamic examples

查看:16
本文介绍了行为:使用动态示例编写场景大纲的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

小黄瓜/行为 示例

Gherkin 语法特性

我的问题

如何使用 Examples 部分中的机密数据进行测试?例如,我想使用用户 ID 或 SSN 号测试内部 API,而不将数据硬编码在功能文件中.

有没有办法从外部源动态加载示例?

更新:github 问题表现项目.

解决方案

我想出了另一个解决方案(behave-1.2.6):

我设法使用 before_feature 为场景大纲动态创建示例.

给定一个特征文件(x.feature):

功能:验证平方数场景大纲:验证 <number> 的正方形然后是<数字>平方是<结果>示例:静态|号码 |结果 ||1 |1 ||2 |4 ||3 |9 ||4 |16 |# 使用标签来标记这个大纲@动态的场景大纲:验证 <number> 的正方形然后是<数字>平方是<结果>示例:动态|号码 |结果 ||.|.|

还有步骤文件(steps/x.step):

from 行为导入步骤@step('{number:d} 的平方是 {result:d}')def step_impl(上下文,数字,结果):断言编号*编号 == 结果

诀窍是在 environment.py 中使用 before_feature,因为它已经将示例表解析为场景大纲,但尚未从大纲生成场景还没有.

导入行为导入副本def before_feature(上下文,特征):features = (s for s in feature.scenarios if type(s) == behavior.model.ScenarioOutline ands.tags 中的动态")对于 s 的特征:对于 s.examples 中的 e:orig = copy.deepcopy(e.table.rows[0])e.table.rows = []对于范围内的数字(1,5):n = copy.deepcopy(orig)# 这依赖于知道表有两行.n.cells = ['{}'.format(num), '{}'.format(num*num)]e.table.rows.append(n)

这只会在带有 @dynamic 标记的场景大纲上运行.

结果是:

behave -k --no-capture特征:验证平方数# features/x.feature:1场景大纲:验证 1 的正方形 -- @1.1 静态 # features/x.feature:8那么 1 的平方是 1 # features/steps/x.py:3场景大纲:验证 2 的正方形 -- @1.2 静态 # features/x.feature:9那么 2 的平方是 4 # features/steps/x.py:3场景大纲:验证正方形 3 -- @1.3 Static # features/x.feature:10那么 3 的平方是 9 # features/steps/x.py:3场景大纲:验证 4 的正方形 -- @1.4 静态 # features/x.feature:11那么 4 的平方是 16 # features/steps/x.py:3@动态的场景大纲:验证正方形 1 -- @1.1 Dynamic # features/x.feature:19那么 1 的平方是 1 # features/steps/x.py:3@动态的场景大纲:验证 2 的正方形 -- @1.2 Dynamic # features/x.feature:19那么 2 的平方是 4 # features/steps/x.py:3@动态的场景大纲:验证正方形 3 -- @1.3 Dynamic # features/x.feature:19那么 3 的平方是 9 # features/steps/x.py:3@动态的场景大纲:验证正方形 4 -- @1.4 Dynamic # features/x.feature:19那么 4 的平方是 16 # features/steps/x.py:31 个功能通过,0 个失败,0 个跳过8 个场景通过,0 个失败,0 个跳过8 步通过,0 失败,0 跳过,0 未定义耗时 0m0.005s

这依赖于将具有正确形状的示例表作为最终表,在我的示例中,有两行.我也不大惊小怪地创建新的 behave.model.Row 对象,我只是从表中复制一个并更新它.为了更加丑陋,如果您使用的是文件,您可以将文件名放在示例表中.

Gherkin / Behave Examples

Gherkin syntax features test automation using examples:

Feature: Scenario Outline (tutorial04)

  Scenario Outline: Use Blender with <thing>
    Given I put "<thing>" in a blender
    When I switch the blender on
    Then it should transform into "<other thing>"

    Examples: Amphibians
        | thing         | other thing |
        | Red Tree Frog | mush        |
        | apples        | apple juice |

    Examples: Consumer Electronics
        | thing         | other thing |
        | iPhone        | toxic waste |
        | Galaxy Nexus  | toxic waste |

The test suite would run four times, once for each example, giving a result similar to:

My problem

How can I test using confidential data in the Examples section? For example, I would like to test an internal API with user ids or SSN numbers, without keeping the data hard coded in the feature file.

Is there a way to load the Examples dynamically from an external source?

Update: Opened a github issue on the behave project.

解决方案

I've come up with another solution (behave-1.2.6):

I managed to dynamically create examples for a Scenario Outline by using before_feature.

Given a feature file (x.feature):

Feature: Verify squared numbers

  Scenario Outline: Verify square for <number>
    Then the <number> squared is <result>

Examples: Static
  | number | result |
  |   1    |    1   | 
  |   2    |    4   |
  |   3    |    9   |
  |   4    |   16   |

  # Use the tag to mark this outline
  @dynamic
  Scenario Outline: Verify square for <number>
    Then the <number> squared is <result>

Examples: Dynamic
  | number | result |
  |   .    |    .   | 

And the steps file (steps/x.step):

from behave import step

@step('the {number:d} squared is {result:d}')
def step_impl(context, number, result):
    assert number*number == result

The trick is to use before_feature in environment.py as it has already parsed the examples tables to the scenario outlines, but hasn't generated the scenarios from the outline yet.

import behave
import copy

def before_feature(context, feature):
    features = (s for s in feature.scenarios if type(s) == behave.model.ScenarioOutline and
                'dynamic' in s.tags)
    for s in features:
        for e in s.examples:
            orig = copy.deepcopy(e.table.rows[0])
            e.table.rows = []
            for num in range(1,5):
                n = copy.deepcopy(orig)
                # This relies on knowing that the table has two rows.
                n.cells = ['{}'.format(num), '{}'.format(num*num)]
                e.table.rows.append(n)

This will only operate on Scenario Outlines that are tagged with @dynamic.

The result is:

behave -k --no-capture
Feature: Verify squared numbers # features/x.feature:1

  Scenario Outline: Verify square for 1 -- @1.1 Static  # features/x.feature:8
    Then the 1 squared is 1                             # features/steps/x.py:3

  Scenario Outline: Verify square for 2 -- @1.2 Static  # features/x.feature:9
    Then the 2 squared is 4                             # features/steps/x.py:3

  Scenario Outline: Verify square for 3 -- @1.3 Static  # features/x.feature:10
    Then the 3 squared is 9                             # features/steps/x.py:3

  Scenario Outline: Verify square for 4 -- @1.4 Static  # features/x.feature:11
    Then the 4 squared is 16                            # features/steps/x.py:3

  @dynamic
  Scenario Outline: Verify square for 1 -- @1.1 Dynamic  # features/x.feature:19
    Then the 1 squared is 1                              # features/steps/x.py:3

  @dynamic
  Scenario Outline: Verify square for 2 -- @1.2 Dynamic  # features/x.feature:19
    Then the 2 squared is 4                              # features/steps/x.py:3

  @dynamic
  Scenario Outline: Verify square for 3 -- @1.3 Dynamic  # features/x.feature:19
    Then the 3 squared is 9                              # features/steps/x.py:3

  @dynamic
  Scenario Outline: Verify square for 4 -- @1.4 Dynamic  # features/x.feature:19
    Then the 4 squared is 16                             # features/steps/x.py:3

1 feature passed, 0 failed, 0 skipped
8 scenarios passed, 0 failed, 0 skipped
8 steps passed, 0 failed, 0 skipped, 0 undefined
Took 0m0.005s

This relies on having an Examples table with the correct shape as the final table, in my example, with two rows. I also don't fuss with creating new behave.model.Row objects, I just copy the one from the table and update it. For extra ugliness, if you're using a file, you can put the file name in the Examples table.

这篇关于行为:使用动态示例编写场景大纲的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆