黄瓜迁移场景到场景大纲

Posted

技术标签:

【中文标题】黄瓜迁移场景到场景大纲【英文标题】:Cucumber migrate scenario to scenario outline 【发布时间】:2020-07-11 09:42:30 【问题描述】:

我想将多行场景移动到场景大纲中,以便可以将表格的各个行作为单独的测试进行测试。这是我想到的一个简化示例:

Scenario: This scenario loops through the lines of the table performing an assert on each line
    When I do something and verify it
      | name         | parameter1 | parameter2   | parameter3 |
      | A and 1      | A          | 1            | true       |
      | B and 1      | B          | 1            | false      |
      | A and 2      | A          | 2            | false      |
      | B and 2      | B          | 2            | true       |

步骤定义如下所示:

@When("I do something and verify it")
public void doSomethingAndVerifyIt(DataTable dataTable) 
    List<Map<String, String>> keyValues = dataTable.asMaps();
    for (Map<String, String> keyValue : keyValues) 
        assertSomething(keyValue.get("parameter1"), keyValue.get("parameter2"), keyValue.get("parameter3"));
    

这工作正常,但如果任何行未能通过断言步骤,则测试将在此时停止。我想将其更改为使用沿这些线的场景大纲,以便这些线可以彼此独立地通过或失败:

Scenario Outline: This scenario loops through the lines of the table performing an assert on each line
    When I do something and verify it

Examples:
      | name         | parameter1 | parameter2  | parameter3 |
      | A and 1      | A          | 1           | true       |
      | B and 1      | B          | 1           | false      |
      | A and 2      | A          | 2           | false      |
      | B and 2      | B          | 2           | true       |

如何更改步骤定义,以便每次测试读取一行?我知道我可以通过在步骤定义下添加一行来按名称显式声明每个参数来做到这一点,但在我的情况下,这将涉及大量参数。

有没有更简单的方法来做到这一点:

@When("I do something and verify it")
public void doSomethingAndVerifyIt(Map<String, String> keyValue) 
    assertSomething(keyValue.get("parameter1"), keyValue.get("parameter2"), keyValue.get("parameter3"));

【问题讨论】:

【参考方案1】:

您必须在步骤定义中使用列标题作为参数,以便黄瓜可以将参数替换为表中的值,例如

Scenario Outline: eating
  Given there are <start> cucumbers
  When I eat <eat> cucumbers
  Then I should have <left> cucumbers

  Examples:
    | start | eat | left |
    |    12 |   5 |    7 |
    |    20 |   5 |   15 |




【讨论】:

是的,我知道在步骤中将参数作为显式参数包含在内是可行的,但老实说,我希望避免这种情况。我有很多参数,并希望将它们作为示例表中每一行的 Map 读入,而不是单独声明它们。这似乎是一件很自然的事情! 你不能这样做 Cucumber 将无法知道如何处理它们。如果你有复杂的数据要编程到场景中,你应该采用我的第一种方法。在场景中放置大量数据行是一种非常糟糕的反模式。我知道功能编程似乎是一件很自然的事情,但这与它们的设计和功能完全相反。将每一行数据(每个示例)转化为规则。它不仅会让你的场景变得更好,如果你允许的话,它还会帮助你更好地编码。【参考方案2】:

关于如何使用表格,请参阅我的其他答案。

改进方案的更好方法是将示例转换为命名规则。 在讨论行为时从业务中获取信息时,示例非常有用。但是,在编写代码时,它们并不是很好。让我们通过密码登录来探索一下。

说我们有

password     | success?

123456       |   no
xb32drthcyfe |   no
p@ssword1    |   yes

作为我们的例子。我们这里的问题是我们不知道为什么xb32drthcyfe 应该失败而p@ssword1 应该成功。我们可以猜测,但我们的场景未能记录 WHY。

现在考虑

Scenario: Passwords must contain a symbol
 When I register with a password without a symbol
 Then I should see my password needs a symbol

现在您有了一个场景,不仅可以记录 WHY,还可以让您挑战 WHY,并探索 WHY,例如

Scenario: Weak password that contains a symbol
 Given my password is long enough has a symbol but it is really weak
 When I register with my password
 Then I should be registered.

现在您可以向您的企业展示上述行为并说,我们真的要这样做吗?

每个示例背后都应该有一个唯一的命名规则。为了让示例变得足够成熟以驻留在您的 ckes 中,您需要揭示此规则,为其命名,然后将示例在您的 ckes 中的用法替换为探索规则的场景。

【讨论】:

感谢您的帮助。运行这些测试的两种方法之间存在很大差异。一旦一个断言失败,第一个将失败,因此不是表的所有行都可以测试。在第二种方式中,所有四个测试都将运行,并且将报告它们的结果,而不考虑其他行中的通过和失败。规则信息很有趣,但与我的问题并不真正相关。 对不起,你说得对。我从不使用表格或场景大纲,所以请原谅我的错误。帖子的其余部分仍然适用。至于让你的场景大纲起作用,请参阅我的第二个答案。我已经编辑了第一个答案以消除错误。

以上是关于黄瓜迁移场景到场景大纲的主要内容,如果未能解决你的问题,请参考以下文章

恋活怎么让场景卡动起来

黄瓜场景大纲输入,值中带有引号

切换到场景 B 的场景 A 怎么知道用户啥时候完成了场景 B,而场景 A 又重新显示了呢?

使用场景大纲时,黄瓜报告重复

黄瓜不会根据大纲场景找到我的步骤

在 Unity3d 中将游戏对象动态添加到场景中