能否在Gherkin中编写一个“Given When Then When Then”的测试?

31

在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,因此解析它不是问题。我只是想编写更好的测试。我可以在第一个then中写下And the Registration Wizard should be filled out with data,但那似乎不够具体...建议?

我认为这个问题有所帮助,但在这个特定的应用程序中,是QA与开发一起编写这些测试。我们想要尽可能多地使用mink和behat来使用selenium。但是,根据我目前所了解的内容,mink具有这种能力,有点违背了书面测试用例的核心。然而,同时我也想以一种方式编写测试用例,实现完整的测试覆盖。 - General Redneck
1
我撤销了对我的问题的编辑,因为它不再代表原始的例子verbetium... 此外,在"And"步骤之前使用制表符是完全可以接受的,并且可以在文档这里中看到。 - General Redneck
5个回答

35

这取决于写作的功能目标受众。看起来你所拥有的Gherkin脚本可能不是由利益相关者(即非技术人员,但对业务和网站有着既得利益的人)编写的。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,则现在需要重构您的需求......)。
我最初也有很多像你一样的gherkin规格 - 我仍然偶尔使用它们。一旦你的测试框架建立起来了,gherkin就成为了一种非常好的方式,用于编写数据驱动/可配置的单元测试;它们对我的开发流程仍然具有巨大的价值。但我确实尝试通过文件夹和标签/类别将更“纯粹”的规格与我的“开发人员”规格分开。
编辑:我想总结一下,你所拥有的是一个很棒的“测试”,但是相对而言是一个相当糟糕的“需求”。但还是坚持使用吧!

14

当真实场景需要时,Gherkin的场景中可以使用多个When/Then循环。SaxonMatt's answer指出了一个极好的观点,即场景最好用利益相关者的语言而非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循环编写此场景:
  • Before the user checks out, they should see one product in their shopping cart (only as a digit in the site header, so the step doesn't mention the product name). There is no way to test this requirement at the end of the scenario. (Well, the test could collect the information immediately after the user adds the product to their cart and assert the expected count at the end of the scenario, but that would be pointlessly sneaky and confusing.) Instead, assert the correct count at the natural place in the scenario, as soon as it is visible to the user.

    Similarly, Then I should see the account creation form and Then I should see the checkout form with 1 product, "Elliptical Juicer" can test important requirements at the points in the scenario at which it is natural to test them.

  • Suppose we didn't care about what the user sees during the process, only whether they get to the end of the scenario with their product on the way. We might then omit the intermediate Then steps:

    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 comes as a surprise, doesn't it? It requires the reader to infer that a guest user is asked to create an account during checkout. It's clearer to say so explicitly, as in the first version of the scenario that I gave.

  • Suppose none of the above concerns convinced us and we wrote a separate Gherkin scenario for each point in the overall scenario where we needed to assert that requirements have been met:

    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"
    

    That's awful! First, none of the scenarios is what a stakeholder would think of as a scenario. Second, when one of the intermediate states changes, two steps will have to change: the step which asserts the intermediate state and the Given step which sets up the intermediate state for the next scenario. Each of those Given steps is an opportunity to set up the wrong state, i.e. make an integration error. This set of scenarios has much less value as an integration test suite than did the single scenario. You might almost have written a series of unit tests.

"写完整的场景很可能会导致一些重复。就像你在单元测试中容忍重复的程度比在常规代码中容忍更多一样,在Gherkin场景中容忍重复更多。不要妥协可理解性。分解场景并仅在关键点(例如上面示例中创建产品)使用Given,并且这样做时知道你正在削弱场景的集成测试能力。

此外,请记住验收测试应该只是自动化测试套件的一部分。仅编写足够的验收测试以涵盖关键场景,并使用单元测试覆盖详细信息。通常,解决验收测试之间的重复的解决方案是用单元测试替换其中一个。"


1
你的多个 When/Then 对听起来很像需要自己的场景的独特功能。 - Brenden

5
我也会说不。
在我的另一篇文章中,Daniel 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/

3
我认为不行。
当测试失败时,应该告诉你在你的系统中故障出现在哪里。类似你示例中的长测试往往是脆弱的,并需要更高级别的维护。
你需要定义你的测试正在测试什么(应该只有一个),并阅读你的测试
- 它可以是表单验证测试。 - 它可以是注册测试。 - 它可以是用户仪表板测试。
这将需要一定的时间来调查故障发生的位置以及它与代码的关系。

好的决定。事实上,这也是最终发生的事情。但是将一些步骤“更加通用化”也有所帮助。 - General Redneck

0

我也会说不。

给定条件是设置的前提条件。 当时是一个动作(可以是无操作)。 然后形式断言。

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

一旦第一个Then失败,这将变得更加有用,以便本地化问题。


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