编写真正的 bdd cucumber 功能/场景的最佳实践
我们是 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 "[email protected]"
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 "[email protected]" exists
When I visit the grant dossier access page
And I fill in "eMail-Address" with "[email protected]"
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 "[email protected]" exists
When I visit the grant dossier access page
And I fill in "eMail-Address" with "[email protected]"
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
您更喜欢哪一种,为什么?
We are new to bdd/ cucumber and discussing in out team how to write correct feature/ scenarios.
We came up with the two following approaches, which should almost describe/ solve the same requirement:
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."
The second one:
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 "[email protected]"
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 "[email protected]" exists
When I visit the grant dossier access page
And I fill in "eMail-Address" with "[email protected]"
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 "[email protected]" exists
When I visit the grant dossier access page
And I fill in "eMail-Address" with "[email protected]"
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
Which one would you prefer and why?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
编写 Cucumber 测试的目的是创建一个关于代码功能的规范,该规范可供团队中无法阅读代码的人员阅读。我首先会问他们更喜欢哪一个。
我的猜测是他们会更喜欢第一个,因为它更具声明性。因为它是在更高的抽象级别上编写的(而不是关心单击页面上的小部件),所以更容易阅读。
与 Josh 所说的相反,我认为制定可以通过 UI 运行或不通过 UI 运行的步骤是一个非常好的主意。将 UI 问题暴露在某个功能上可能会使其难以进行合理的设计更改,而且读起来也相当无聊。
我最近做了一个关于这个主题的演讲,我认为它与你所处的位置非常相关:
http://skillsmatter.com/podcast/agile-testing/refuctoring-your-cukes
另请参阅这些相关博客文章:
祝你好运!
The point of writing Cucumber tests is to create a specification about what the code does that can be read by the people on your team who can't read code. I'd start by asking them which one they prefer.
My guess is they'll prefer the first one, because it's more declarative. Because it's written at a higher level of abstraction (rather than being concerned with clicking widgets on a page) it's easier to read.
Contrary to what Josh said, I think having steps that could work either through a UI or not is a really good idea. Surfacing UI concerns on a feature can make it brittle to legitimate design changes, and also rather boring to read.
I did a talk recently about this subject, I think it's really relevant to where you're at:
http://skillsmatter.com/podcast/agile-testing/refuctoring-your-cukes
See also these relevant blog posts:
Good luck!
一般来说,我会选择更容易被客户或开发人员以外的人阅读的解决方案。使用 Cucumber 这样的工具的一大优点是它读起来就像一个故事。您的目标应该是使每个测试足够简单,以便客户可以阅读您的验收测试并了解哪些功能已经实现。这对您有利,因为您的客户可以放心,因为知道某些功能已经进行了验收测试。
话虽如此,我认为第一个解决方案比第二个解决方案更能代表可读风格。
比
我认为
。你不一定需要在每个场景前加上“我可以”或“我不能”前缀,但可以轻松地走向完整的想法。
更新
在您的评论中,您询问了验证错误以及如何使用选项 1 处理该错误。我认为您这里有几个选项:
选项 1
优点:
您不必费心使用其他框架来测试您的验证。您的大部分测试将包含在 Cucumber 中。您的客户可以在一处查看您的所有测试。
缺点:
您的 Cucumber 测试将包含不同级别的粒度。您的客户可能更关心高级功能,而不是看到所有细节都通过。如果我是一位有兴趣使用 Cucumber 测试作为已实现和测试功能的基础的客户,我会更喜欢一个更小、更易读的测试用例列表,而不是一个包罗万象的测试用例列表。我最多可能希望看到向用户呈现错误消息 - 您可以在一个场景大纲中执行此操作。
选项 2
优点:
您可以将测试问题划分为适当的粒度级别。正如我在选项 1 的缺点中提到的,与较低级别的详细信息相比,您的客户很可能对较高级别的功能感兴趣。您可以在 RSpec 单元测试中测试验证是否通过,并使用 Cucumber 快速测试用户是否看到错误消息,如果您有无效记录(再次使用场景大纲,或者只是测试看看是否只有一条验证消息使到前端)。主要的一点是,更注重功能测试的 Cucumber 不应该测试与模型相关的每一个小事情 - 让 RSpec 或另一个单元测试框架来处理它。
缺点:
您必须使用另一个框架来实现更细粒度的期望。使用另一个框架意味着需要更多的时间来学习它,等等。而且很难知道如何平衡何时使用一个框架而不是另一个框架,即“我应该在这里使用 Cucumber 还是 RSpec?”
据我所知,选项 2 目前最受欢迎。团队使用适合每个粒度级别的框架,并且他们尝试远离“all in”方法。
I would go with the solution that is more easily readable by your customers, or people other than developers, in general. A big advantage of using tools like Cucumber is that it reads like a story. Your goal should be to make each test simple enough so that a customer can read your acceptance tests and realize which features are already implemented. This benefits you because your customers can rest easy knowing that certain features have acceptance tests in place.
Having said that I think the first solution represents the readable style more than the second solution.
is easier to read than
in my opinion.
You don't necessarily need to prefix each scenario with "I can" or "I cannot", but ease towards the side of a complete thought.
Update
In your comment you asked about validation errors and how you should handle that with option 1. I think you have a couple of options here:
Option 1
pros:
You don't have to bother using another framework to test your validations. Most of your tests will be included in Cucumber. Your customers can see all of your tests in one place.
cons:
Your Cucumber tests will have varying levels of granularity included. Your customers probably care more about the high-level features than they do about seeing all of the nitty-gritty details pass. If I were a customer interested in using your Cucumber tests as a basis for what features have been implemented and tested, I would prefer a smaller, more readable list of test cases than an all encompassing one. At most I'd probably like to see that error messages are presented to the user - and you can do this in one Scenario Outline.
Option 2
pros:
You separate your testing concerns into appropriate levels of granularity. As I mentioned in the cons for Option 1, your customers are most likely interested in the higher level features than the lower level details. You can test whether validations pass or not in your RSpec unit tests, and use Cucumber to quickly test that the user sees error messages if you have an invalid record (again using Scenario outlines, or maybe just test to see if only one validation message makes it to the front end). The main point is that the more functional-test-oriented Cucumber should not test every little thing concerned with Models - let RSpec or another unit testing framework handle that.
cons:
You have to use another framework to exercise the more fine-grained expectations. Using another framework means taking more time to learn it, etc. Also it's hard to know how to balance when to use one framework over the other, i.e. "should I use Cucumber or RSpec here?"
From what I have read, Option 2 is the most popular right now. Teams use the frameworks appropriate for each level of granularity, and they try to stay away from an "all in" approach.
如果按照黄瓜制造商的标准,第一组显然是赢家。
这篇博文“辅助轮脱落”由(其中之一?)黄瓜制造商(Aslak Hellesøy)的目标正是针对您编写的两个选项之间的差异。他毫不含糊地解释说,声明性的、以领域为中心的、易于理解的功能是 Cucumber 用户应该努力实现的功能,也是使您的选项 1 成为赢家的原因。
他基本上说,尝试在系统语言中实现 DRY 功能 步骤(单击这个、选择那个等)是 Cucumber 中的代码味道。用他的话说:
顺便说一句,这里很多人都说过 Cucumber 的目的是让客户更容易阅读和理解。我认为这有点偏离目标,易于理解并不是目的。我认为他们制作 Cucumber 是为了确保客户和开发人员使用相同的语言并朝着相同的结果努力。因此,这既是为了让开发人员站在客户的角度思考,也是为了帮助客户了解开发过程。
The first set is the clear winner if you go by the standards of the makers of cucumber.
This blog post, "The training wheels came off" by (one of?) the maker of cucumber (Aslak Hellesøy), is aimed squarely at the difference between the two options that you wrote. In no uncertain terms, he explains that declarative, domain focused, easy to understand features are what users of cucumber should be trying to achieve and are what make your option 1 the winner.
He basically says that trying to achieve DRY functional steps in the system language (click on this, select that, etc.) are a code smell in Cucumber. In his words:
By the way, many people here have said that the purpose of Cucumber is to make things easier to read and understand for the customer. I think that is slightly off target and ease of understanding is not the purpose. I think they made Cucumber to ensure that the customer and developer are speaking the same language and working toward the same results. So it is as much about making developers step into the shoes of the customer as it is about helping the customer to see into the development process.
我更喜欢第一种场景,因为它以更好的方式描述了该功能的工作原理
此外,您还可以使用场景大纲进行测试重构,请查看此博客文章,使用 cucumber http://eggsonbread.com/2010/09/06/my-cucumber-best -practices-and-tips/
在第一种方法中,您必须执行自己的步骤,但是当您有以下情况时,您将多次使用相同的场景并减少代码重复:
我填写“电子邮件地址” " 与 "[电子邮件受保护]"
我用“[电子邮件受保护]”填写“电子邮件地址”
在不同的场景中。我希望在这里表达我的观点。
另外,我强烈推荐您rspec 书,以及
://confreaks.net/videos/72-mwrc2009-bdd-with-cucumber" rel="nofollow">名为“
I prefer the first kind of scenario, because it describes in a better way how the feature works
Also, you have test refactoring to do there with Scenario Outlines, check this blog post, it's great to work with cucumber http://eggsonbread.com/2010/09/06/my-cucumber-best-practices-and-tips/
In the first approach you'll have to do your own steps, but you will using more times the same scenario and reduce code duplications when you have:
And I fill in "eMail-Address" with "[email protected]"
And I fill in "eMail-Address" with "[email protected]"
in separate scenarios. I hope to made my point here.
Also I strongly recommend you the rspec book, and a talk called outside-in development with cucumber
Greetings
这种 BDD 的重点是为组织内的非技术决策者/负责人提供可读、可理解的规范(以减少决策者和实施者之间的沟通问题)。
为此,第一个示例中的样式比第二个示例中的样式更简单。简单的。
The whole point of this kind of BDD is to provide readable, understandable specs for non-technical decision-makers/principals within an organization (to reduce communication woes between decision-makers and implementors).
To this end, the style in your first example is a no-brainer over the second example. Easy.
我更喜欢这两种方法中的第二种。以下是我对方法 1 的担忧。
可以不通过UI来实现,这是一个危险。如果是的话,那么对于用户如何授予访问权限存在一定程度的期望,而无需进行测试。 Cucumber 的亮点在于从 UI 一直进行测试(通过 UI 进行测试)。
我也有同样的担忧
可以通过调用确实经过 UI 的步骤来实现步骤定义中的每个步骤,但除非这是真的,否则我仍然会有这个担忧。
总之,我担心方法 1 没有经过测试通过用户界面。
I prefer the 2nd approach of the two. Here are my concerns with Approach 1.
Can be implemented without going through the UI, which is a danger. If it were there is a whole level of expectations about how users grant access that wouldn't be tested. Cucumber shines is testing from the UI all the way down (by testing through the UI).
I have the same concern about
It's possible to be implementing each of these steps in the step definitions by calling steps that do go through the UI, but unless that's true I would still have this concern.
In sum, I'm concerned that Approach 1 doesn't test through the UI.