编写真正的bdd黄瓜功能/场景的最佳实践

时间:2011-03-30 13:28:51

标签: ruby-on-rails-3 cucumber bdd

我们是bdd / cucumber的新手,并在团队中讨论如何编写正确的功能/场景。

我们提出了以下两种方法,几乎​​可以描述/解决相同的要求:

Feature: Give access to dossiers to other registered users
  As a logged in user
  In order to show my dossier to other users
  I want to give other users (limited) access to my dossiers

  Background:
    Given I am logged in as "Oliver"
    And another user "Pascal" exists
    And another user "Tobias" exists

  Scenario: I can give access to my own dossier
    When I grant access to "Pascal" with permisson "readonly"
    Then I should see "Access granted."
    And user "Pascal" should have permission "readonly" on dossier "Oliver"

  Scenario: I can give access to a created dossier
    Given I created a new dossier "Max Müller"
    When I grant access on dossier "Max Müller" to "Pascal" with permisson "readonly"
    Then I should see "Access granted."
    And user "Pascal" should have permission "readonly" on dossier "Max Müller"

  Scenario: I can give access to a managed dossier
    Given I manage the dossier from "Tobias"
    When I grant access on dossier "Tobias" to "Pascal" with permisson "readonly"
    Then I should see "Access granted."
    And user "Pascal" should have permission "readonly" on dossier "Tobias"

  Scenario: I cannot give access to a writable dossier
    Given I have write access to the dossier from "Tobias"
    When I follow "Grant access"
    Then I should see "You are not allowed to grant access on this dossier."

  Scenario: I cannot give access to a readonly dossier
    Given I have readonly access to the dossier from "Tobias"
    When I follow "Grant access"
    Then I should see "You are not allowed to grant access on this dossier."

  Scenario: I can give access to a dossier with an expiration date
    Given I created a new dossier "Max Müller"
    When I grant access on dossier "Max Müller" to "Pascal" with permisson "readonly" until "2020-01-01"
    Then I should see "Access granted till 2020-01-01."
    And user "Pascal" should have permission "readonly" on dossier "Max Müller" until "2020-01-01"

  Scenario: I cannot transfer a created dossier to a new owner who is already registered
    Given I created a new dossier "Max Müller"
    When I transfer dossier "Max Müller" to "Pascal"
    Then I should see "Pascal already has a dossier, transfer not possible."

第二个:

Feature: Grant access on dossiers to registered users
  As a logged in user
  In order to allow others to view/ manage dossiers I have access to
  I want to give access of those to other users

  Background:
    Given I am logged in as "gucki@email.com"
    And I am working with my own dossier

  Scenario: Invalid data entered 
    When I visit the grant dossier access page
    And I press "Grant access"
    Then I should see a validation error on "eMail-Address"

  Scenario: Valid data entered 
    Given a user "pascal@email.com" exists
    When I visit the grant dossier access page
    And I fill in "eMail-Address" with "pascal@email.com"
    And I select "readonly" from "Permissions"
    And I press "Grant access"
    Then I should see "Access granted."
    And I should be on the dossiers page

  Scenario: Valid data entered with expiry date 
    Given a user "pascal@email.com" exists
    When I visit the grant dossier access page
    And I fill in "eMail-Address" with "pascal@email.com"
    And I select "readonly" from "Permissions"
    And I fill in "Valid until" with "2010-03-01"
    And I press "Grant access"
    Then I should see "Access granted till 2010-03-01."
    And I should be on the dossiers page

  Scenario: Display calendar on click on "Valid until"
    When I click on the field "Valid until"
    Then a calendar popup should be displayed
    When I click on "1943-01-02"
    Then the field "Valid until" should be have "1943-01-02"
    And the calendar popup should be hidden

  Scenario: Only allow to grant access to categories I have access to myself
    Given I have limited access to the working dossier 
    When I visit the grant dossier access page
    Then I should not see categories I have no access to

  Scenario: Dossier with permission "manager" can only grant readonly, readwrite
    Given I have the permission "manager" on my working dossier 
    When I visit the grant dossier access page
    Then I should only see the permissions "readonly, readwrite"

  Scenario: Dossier with permission "readwrite" is not allowed to grant any permissions
    Given I have the permission "readwrite" on my working dossier 
    When I visit the grant dossier access page
    Then I should the see the error "You cannot grant access on this dossier!"
    And I should be on the dossiers page

您更喜欢哪一个?为什么?

6 个答案:

答案 0 :(得分:13)

编写Cucumber测试的目的是创建一个规范,说明代码可以由团队中无法读取代码的人员读取的内容。我首先问他们喜欢哪一个。

我的猜测是他们更喜欢第一个,因为它更具说明性。因为它是在更高的抽象层次上编写的(而不是关注单击页面上的小部件),所以它更容易阅读。

与Josh所说的相反,我认为通过UI可以实现的步骤是一个非常好的主意。对功能进行表面处理UI问题可能会使合法的设计变更变得脆弱,而且阅读也很无聊。

我最近就这个主题做了一个演讲,我认为这与你所处的位置非常相关: http://skillsmatter.com/podcast/agile-testing/refuctoring-your-cukes

另见这些相关的博文:

祝你好运!

答案 1 :(得分:6)

一般来说,我会选择客户或开发人员之外更容易阅读的解决方案。使用像Cucumber这样的工具的一大优势是它看起来像一个故事。您的目标应该是使每个测试足够简单,以便客户可以阅读您的验收测试并了解哪些功能已经实施。这对您有利,因为您的客户可以轻松地知道某些功能已经进行了验收测试。

话虽如此,我认为第一种解决方案比第二种解决方案更能代表可读风格。

  

“我可以通过电子邮件访问档案   到期日“

更容易阅读
  

“输入有效期限的有效数据”

在我看来。

您不一定需要为每个场景添加“我能”或“我不能”的前缀,但要轻松地走向完整思考的一面。

<强>更新

在评论中,您询问了验证错误以及如何使用选项1处理验证错误。我认为您有两个选择:

  1. 黄瓜的完整验证测试
  2. 在Cucumber中进行部分验证测试(错误呈现给用户),在RSpec中进行部分测试(抛出错误) - 或其他一些单元测试框架。
  3. 选项1

    优点:

    您不必费心使用其他框架来测试您的验证。大多数测试都将包含在Cucumber中。您的客户可以在一个地方看到您的所有测试。

    缺点:

    您的黄瓜测试将包含不同级别的粒度。您的客户可能更关心高级功能,而不是关注所有细节的细节。如果我是一个有兴趣使用您的Cucumber测试作为实现和测试功能的基础的客户,我宁愿选择一个更小,更易读的测试用例列表,而不是一个包含所有测试用例的测试用例。最多我可能希望看到错误消息呈现给用户 - 您可以在一个场景大纲中执行此操作。

    选项2

    优点:

    您将测试问题分成适当的粒度级别。正如我在选项1的缺点中提到的,您的客户很可能对较高级别的功能感兴趣,而不是对较低级别的详细信息感兴趣。您可以在RSpec单元测试中测试验证是否通过,如果您的记录无效,可以使用Cucumber快速测试用户是否看到错误消息(再次使用Scenario轮廓,或者只是测试以查看是否只有一条验证消息它到前端)。重点是更多功能测试导向的Cucumber不应该测试与模型有关的每一件小事 - 让RSpec或其他单元测试框架处理它。

    缺点:

    您必须使用另一个框架来实现更细粒度的期望。使用另一个框架意味着花更多的时间来学习它等。另外很难知道如何平衡何时使用一个框架而不是另一个框架,即“我应该在这里使用Cucumber还是RSpec?”

    据我所知,选项2现在最受欢迎。团队使用适合每个粒度级别的框架,他们试图远离“全押”方法。

答案 2 :(得分:5)

如果按照黄瓜制造商的标准,第一套就是明显的赢家。

黄瓜制造商(AslakHellesøy)(黄色制造商之一?)的博客文章"The training wheels came off"正是针对你所写的两个选项之间的差异。毫无疑问,他解释说,黄瓜用户应该尝试实现的声明性,以领域为中心,易于理解的特征,并使您的选择1成为赢家。

他基本上说,尝试在系统语言中实现DRY 功能性 步骤(点击此处,选择它等)是Cucumber中的代码气味。用他的话说:

  

如果您只需要一个用于驱动鼠标和键盘的测试工具,   不要使用黄瓜。还有其他工具可以实现此目的   与Cucumber相比,抽象和打字开销要少得多。

顺便说一下,很多人都说黄瓜的目的是让客户更容易阅读和理解。我认为这有点偏离目标,而且易于理解不是目的。我认为他们让Cucumber确保客户和开发人员使用相同的语言并努力获得相同的结果。因此,让开发人员踏上客户的道路,同时帮助客户了解开发过程也是如此。

答案 3 :(得分:4)

我更喜欢第一种情况,因为它更好地描述了该功能的工作原理

此外,您还有使用场景大纲进行测试重构,请查看此博客文章,使用黄瓜http://eggsonbread.com/2010/09/06/my-cucumber-best-practices-and-tips/非常棒

在第一种方法中,您必须执行自己的步骤,但是当您拥有以下内容时,您将使用相同场景的更多次并减少代码重复:

我用“pascal@email.com”填写“电子邮件地址”  我用“tobias@email.com”填写“电子邮件地址”

在不同的场景中。我希望在这里说明我的观点。

另外,我强烈建议您the rspec booktalk called outside-in development with cucumber

问候

答案 4 :(得分:2)

这种BDD的重点是为组织内的非技术决策者/负责人提供可读,易懂的规范(以减少决策者和实施者之间的沟通困境)。

为此,第一个示例中的样式比第二个示例更简单。容易。

答案 5 :(得分:1)

我更喜欢两者的第二种方法。以下是我对方法1的关注。

  

当我授权访问档案“Max   Müller“to”Pascal“与许可   “只读”

可以在不通过UI的情况下实施,这是一种危险。如果是这样的话,对于用户如何授予无法测试的访问权限存在一定程度的期望。黄瓜闪耀正在从UI一直向下测试(通过UI测试)。

我对

有同样的担忧
  

用户“Pascal”应该有   在档案中“读取”许可“Max   米勒“

通过调用通过UI的步骤,可以在步骤定义中实现这些步骤中的每个步骤,但除非确实如此,否则我仍然会有这种担忧。

总而言之,我担心方法1不会通过UI进行测试。