Gherkin 场景、可重用步骤方法或特定方法

Gherkin scenarios, reusable steps approach or specific approach

我需要有关如何编写场景的建议。首先,我必须解释一下,我们有一个 CQRS 架构,其中命令和查询是分开的 API。我们使用 Specflow 中用于创建测试的 Gherkin 场景指定命令。

在下面的场景中,域是费用的域。费用束是费用的集合。在这种情况下,我想指定并测试我不能为其他人创建的费用包创建费用。我只能为我创建的费用包创建费用。

下面的做法是我尽量复用步骤:

Background: 
  Given I am declarant 'Marieke'

     Scenario: Not allowed to create expense for a bundle that was created by another declarant
     Given the following expense bundles exist
        | declarant | name             | administration    | status        |
        | Lucy      | Trip to New York | Company B.V.      | not submitted |
       When I create an expense for the following expense bundle
        | declarant | name             | administration    | status        |
        | Lucy      | Trip to New York | Company B.V.      | not submitted |
       Then the expense is not created for the expense bundle

名称、管理和状态在上面的示例中可能不相关。但在其他情况下,我可以重复使用 'given the following expense bundles exist' 步骤。这为开发人员节省了时间。

在以下方法中,我尝试编写一个更易读且更具体的场景:

Background: 
  Given I am declarant 'Marieke'

    Scenario: Not allowed to create expense for a bundle that was created by another declarant
       When I create an expense for an expense bundle that was created by another declarant
       Then the expense is not created for the expense bundle

在这种情况下,开发人员必须编写一个可能永远不会再次使用的 When 步骤。这是个问题吗?

在我的场景中,我对这两个选项都感到很纠结。有什么建议吗?

我会使用第一个选项。意思更清楚,因为您可以定义其他声明者是谁。如果开发人员选择使用 Marieke 作为首选声明者,则测试用例会因不明原因而失败。此外,如果需要,您可以使用 'Same name, same administration' 等其他测试用例扩展测试集。 可重用性是自动化的一大优势,它还节省了您与开发人员之间沟通的时间,根据我的经验,这几乎与自己编写代码一样耗时。

写场景的方式过于解释是什么和为什么,而对事情是如何完成的一无所知。什么是关于报销费用包,特别是您不能为其他人报销费用。您还没有真正解释为什么这很重要,您可以在功能序言中做到这一点。这个场景不应该在乎费用包是多少。这些场景的其他问题是语言似乎有点笨拙。同样,您可以使用序言来解释什么是费用包。所以我会写类似

的东西
Feature: Claiming an expense on an expense bundle

Explain what an expense bundle is, including the concept of ownership
Explain what an expense is
Explain why Fred should not be able to claim an expense on Susan's expense bundle

Background:
  Given users Fred and Susan
  And Susan has an expense bundle

  Scenario: Susan claims an expense
    When Susan claims an expense on her bundle
    Then the expense should be approved

  Scenario: Fred claims an expense on Susan's bundle
   When Fred claims an expense on Susan's expense bunlde
   Then the expense should be rejected

这将是我的起点,我会用它来提示问题,例如

  1. 为什么 Fred 可以看到 Susan 的费用包
  2. 当 Fred 试图报销费用时,我们是否应该通知某人(Susan、Fred 的老板、Fred)
  3. ...

如果您正确编写了步骤定义,则重复使用步骤定义是无关紧要的。编写步骤定义的正确方法是让每个步骤都单独调用一个辅助方法。通过这种方式,步骤定义被简化为执行一个单一的功能——将业务语言翻译成呼叫。所以一个步骤是否只使用一次(大多数不是)并不重要,因为编写它是微不足道的。

在辅助方法中重用代码是一个完全不同的问题,但是现在我们已经完全在代码中了(而不是在步骤定义中进行了一半)我们可以使用我们所有的常规代码工具和技能来解决那个问题。

使用场景大纲可能是具有最多可重用代码(步骤)的解决方案。我想我缺少一些关于确切功能的上下文,但这可能会让您了解如何处理这个问题。这样做的缺点是当场景中有很多参数时,阅读和解释测试结果可能不是那么容易,所以这也取决于你的目标和谁(测试人员、业务人员、开发人员)将创建和解释测试结果。有关场景大纲的更多信息 https://www.toolsqa.com/cucumber/data-driven-testing-using-examples-keyword/

Abstract Scenario: Don't allow expense creation on bundle of other declarant
Given the expense bundle exists <declarant creator> 
When I create an expense for the bundle <expense creator>, <bundle administration>
Then I expect the bundle expense to be <expected>
Examples:
| bundle creator    | expense creator       | bundle administration | status        | expected    |
| Lucy              | Marieke               | Company B.V.          | Not submitted | Not allowed |
| Marieke           | Lucy                  | Company 2 V.          | Not submitted | Not allowed |
etc..

快乐流淌

Abstract Scenario: Allow expense creation for blabla
Given the expense bundle exists <declarant creator>, <bundle administration> 
When I create an expense for the bundle <expense creator>, <bundle administration>
Then I expect the bundle expense to be <expected>
Examples:
| bundle creator    | expense creator       | bundle administration | status        | expected    |
| Lucy              | Lucy                  | Company B.V.          | Not submitted | Allowed     |
| Lucy              | Lucy                  | Company B.V.          | Not submitted | Allowed     |
etc..