24

在 Gherkin 中编写“Given When Then When Then”测试是否可以接受?一个真实的例子如下 allPlayers.com

Scenario: Successfully register a user
  Given I am on homepage
    And I am not logged into an account
  When I follow "create a new account"
    And I fill in "First Name" with "Bobby"
    And I fill in "Last Name" with "Bricks"
    And I fill in "E-mail" with "bbricks@example.com"
    And I select "Jun" from "Birthday Month"
    And I select "22" from "Birthday Day"
    And I select "1985" form "Birthday Year"
    And I select "Male" from "Gender"
    And I fill in "Password" with "123testing"
    And I fill in "Confirm Password" with "123testing"
    And I solve the captcha math problem
    And I click "Create new account"
  Then I should see "the user dashboard"
    And I should see the Registration Wizard
  When I push "Proceed to next step"
  Then the "First Name" field should contain "Bobby"
    And the "Last Name" field should contain "Bricks".

我知道它使用 behat 工作,所以解析它不是问题。我只是想编写更好的测试。我可以先写,And the Registration Wizard should be filled out with data但这似乎不够具体......

建议?

4

5 回答 5

29

这取决于所写功能的目标受众。您所获得的小黄瓜似乎极有可能不是与利益相关者(即非技术人员但对业务和网站有既得利益的人)一起编写的。BDD 实际上是关于需求和期望的对话——Gherkin 是一种工具,它提供了一种标准/公认的方式,每个人都应该能够阅读,你可以编写需求和期望;以某种方式为开发人员提供自动化测试,也可能为测试人员提供测试脚本。

现在试图脱下我的开发人员帽子 - 我会说业务利益相关者宁愿阅读并轻松理解......

Scenario: Should be able to successfully register on website
    Given I am new to the website
    And I want to register for a user account
    When I go to the registration form
    And I complete all the required registration details correctly
    Then I will be registered on the website
    And I will be automatically logged in

您仍然可以在本规范的幕后构建相同的测试 - 但本规范具有更大的读者群,这是一个任何人都应该理解的更容易理解的要求。我并不是说你拥有的东西没有价值——远非如此。这将是一个非常有效的测试。但它是开发人员特定的,并且与 UI 实现高度耦合(如果您重构/重新设计 UI,您现在需要重构您的需求......)。

我一开始有很多像你一样的小黄瓜规格——我有时仍然使用它们。一旦你的测试框架建立起来,一个小黄瓜是编写数据驱动/可配置单元测试的一种非常好的方式;它们对我的开发过程仍然具有很大的价值。但我确实尝试将更“纯”的规范与我的“开发者”规范分开 - 但文件夹和标签/类别。

编辑:我想总而言之我得到的是......你所拥有的是一个很好的“测试”,但一个相当糟糕的“要求”。坚持下去!

于 2012-08-22T08:43:57.493 回答
11

是的,当现实世界的场景需要它时,在 Gherkin 场景中不止一个When/循环是合适的。Then

SaxonMatt 的回答提出了一个很好的观点,即最好用利益相关者的语言而不是 UI 操作的语言编写场景,这样做通常会缩短场景的长度,但这错过了问题的确切要点。让我们抓住公牛的角。

Gherkin 是为验收测试而设计的:测试利益相关者级别的需求是否已完全实现,即软件是否确实为利益相关者提供了价值。有时提供价值需要不止一个行动-响应周期。考虑以下场景:

Scenario: Guest buys a product
  # This scenario starts with the user not logged in, which doesn't require a step
  Given there is a product named "Elliptical Juicer"

  When I go to the product page for "Elliptical Juicer"
  And I add the product to my shopping cart
  Then I should see 1 product in my shopping cart

  When I request to check out
  Then I should see the account creation form

  When I create an account
  Then I should see the checkout form with 1 product, "Elliptical Juicer"

  When I check out
  Then I should see the checkout success page with 1 product, "Elliptical Juicer"
  And I should receive a checkout confirmation email with 1 product, "Elliptical Juicer"

(请注意,当我在一个场景中有多个When/Then循环时,我喜欢用空行分隔它们,以便它们脱颖而出。)

When最好使用多个/Then循环编写此方案有几个原因:

  • 在用户结帐之前,他们应该在他们的购物车中看到一个产品(仅作为站点标题中的一个数字,因此该步骤没有提及产品名称)。在场景结束时无法测试此要求。(好吧,测试可以在用户将产品添加到他们的购物车后立即收集信息,并在场景结束时断言预期的计数,但这将毫无意义地偷偷摸摸和混淆。)相反,在自然状态下断言正确的计数放置在场景中,只要它对用户可见。

    类似地,Then I should see the account creation form并且Then I should see the checkout form with 1 product, "Elliptical Juicer"可以在场景中自然测试它们的点测试重要需求。

  • 假设我们不关心用户在这个过程中看到了什么,只关心他们是否带着他们的产品到达场景的结尾。然后我们可以省略中间Then步骤:

    Given there is a product named "Elliptical Juicer"
    When I go to the product page for "Elliptical Juicer"
    And I add the product to my shopping cart
    And I request to check out
    And I create an account
    And I check out
    Then I should see the checkout success page with 1 product, "Elliptical Juicer"
    And I should receive a checkout confirmation email with 1 product, "Elliptical Juicer"
    

    And I create an account出乎意料,不是吗?它要求读者推断访客用户在结账时被要求创建一个帐户。更明确地说,就像我给出的场景的第一个版本一样。

  • 假设上述问题都没有说服我们,并且我们为整个场景中的每个点编写了一个单独的 Gherkin 场景,我们需要断言需求已经得到满足:

    Scenario: Guest adds a product to their shopping cart
      Given there is a product named "Elliptical Juicer"
      When I go to the product page for "Elliptical Juicer"
      And I add the product to my shopping cart
      Then I should see 1 product in my shopping cart
    
    Scenario: Guest with a product in their shopping cart attempts to check out
      Given I have a product in my shopping cart
      When I request to check out
      Then I should see the account creation form
    
    Scenario: Guest creates an account
      Given I have a product named "Elliptical Juicer" in my shopping cart
      And I am on the account creation form
      When I create an account
      Then I should see the checkout form with 1 product, "Elliptical Juicer"
    
    Scenario: Newly registered user checks out
      Given I am a user
      And I have a product named "Elliptical Juicer" in my shopping cart
      And I am on the checkout form
      When I check out
      Then I should see the checkout success page with 1 product, "Elliptical Juicer"
      And I should receive a checkout confirmation email with 1 product, "Elliptical Juicer"
    

    那是糟糕的!首先,没有一个场景是利益相关者认为的场景。其次,当中间状态之一改变时,两个步骤将不得不改变:断言中间状态的Given步骤和为下一个场景设置中间状态的步骤。这些Given步骤中的每一个都是设置错误状态的机会,即产生集成错误。这组场景作为集成测试套件的价值远低于单一场景。您可能几乎已经编写了一系列单元测试。

确实,端到端编写每个场景可能会导致一些重复。正如您在单元测试中比在常规代码中更能容忍重复一样,在 Gherkin 场景中比在单元测试中更能容忍重复。不要在可理解性上妥协。分解场景并Given仅在关键点使用 s(例如在上面的示例中创建产品),并且知道您正在稀释场景的集成测试能力。

另外,请记住,验收测试应该只是自动化测试套件的一部分。只编写足够的验收测试来覆盖关键场景,并用单元测试覆盖细节。通常情况下,验收测试重复的解决方案是用单元测试替换一个。

于 2017-07-21T19:58:54.013 回答
5

我也会说不。

在我的另一篇文章中,丹尼尔 F 发现了这篇精彩的文章。以下是相关部分:

Given-When-Then 步骤必须按顺序出现,不能重复。Given 不能跟在 When 或 Then 后面,When 不能跟在 Then 后面。原因很简单:任何一个When-Then 对都表示一个单独的行为。这很容易看出,在上面的测试中,实际上涵盖了两种行为:(1) 从搜索栏搜索,以及 (2) 执行图像搜索。在 Gherkin 中,一种场景涵盖一种行为。因此,应该有两种情况而不是一种。任何时候您想编写多个When-Then 对时,请改为编写单独的场景。(注意:一些 BDD 框架可能允许无序的步骤,但它仍然是反行为的。)

https://automationpanda.com/2017/01/30/bdd-101-writing-good-gherkin/

于 2017-07-12T14:55:15.340 回答
3

我会说不。

当测试失败时,它应该告诉您系统中的哪个位置发生了故障。像您的示例中这样的长时间测试往往很脆弱,需要更高级别的维护。

您需要定义您的测试正在测试什么(这应该是一回事)阅读您的测试

  • 它可能是一个表单验证测试。
  • 这可能是一个注册测试。
  • 它可能是用户仪表板测试。

需要花费大量时间来调查故障在哪里以及与代码中的哪个位置相关。

于 2012-09-18T15:42:16.803 回答
0

我也会说不。

Given 是设置的先决条件。When 是一个动作(可以是什么都不做) Then 形式断言。

如果您需要更多操作,请分解测试。

一旦第一个 Then 无法定位问题,这将变得更加有用。

于 2013-08-27T12:58:53.180 回答