After (My) RSpec best practices and tips, I’m happy to share my Cucumber best practices and tips!
This article will help you organize, clarify and reduce the size of your cucumber scenarios.
1. Organize your garden
Keep your feature files organized by grouping them by business object, then action and context if any. I put all the feature files in the same directory. For instance:
bank_account_add.feature bank_account_delete.feature user_signup.feature user_signup_when_invited.feature user_login.feature
The steps specific to the application should be organized by business object as well (bank_account_steps.rb, user_steps.rb…). Keep the file organized grouping the steps by Given / When / Then.
Do not overload the files generated by Cucumber like step_definitions/web_steps.rb and support/env.rb with your own steps, helpers or setup code. These files are likely to get overwritten when you update Cucumber so store your stuff in your own files.
2. Custom steps make your scenario DRY and accessible
Scenarios should have the same lifecyle as your code: Red, Green, Refactor to make them DRY and easy to read.
Group multiple steps together. For instance:
Given I follow "Send money" When I fill in "Email" with "mukmuk@example.com" And I fill in "Amount" with "10" And I select "Bank account" from "Source" And I press "Send" Then I should see "You've sent $10 to mukmuk@example.com"
… could be refactored to:
Given I send "$10" to "mukmuk@example.com" from my "Bank account"
This step definition is the following:
Given %{I send "$amount" to "$email" from my "$source"} do |amount, email, source|
Given %{I follow "Send money"}
When %{I fill in "Email" with "#{email}"}
And %{I fill in "Amount" with "#{amount.delete('$')}"}
And %{I select "#{source}" from "Source"}
And %{I press "Send"}
Then %{I should see "You've sent $#{amount} to #{email}"}
end
This step can then be easily reused in other scenario keeping your features DRY. It also decouples the scenario from the UI so that you won’t have to change dozens of feature files when the UX guru changes translations or user flows.
3. Background: setup the DRY way
Make the feature focus on one business object/action/context and the background will get longer than the scenarios.
Feature: A user can cancel a transaction unless it's claimed by the recipient
Background:
Given I am logged in
And I send "$10" to "mukmuk@example.com" from my "Bank account"
Scenario: I can cancel as long as the payment is not claimed
When I cancel my latest transaction
Then I should see a cancellation confirmation
Scenario: I can't cancel once the payment is claimed
Given "Mukmuk" claimed the latest transaction
Then I can't cancel my latest transaction
4. Scenario outlines: scenario with variables!
A scenario outline contains variables allowing you to test multiple context using a truth table. For instance I use them to make sure that validation errors are displayed properly:
Scenario Outline: Add invalid bank account displays inline errors
Given I follow "Add Bank Account"
When I fill in "<field>" with "<value>"
And I press "Add Bank Account"
And I should see the inline error "<error>" for "<field>"
Examples:
| field | value | error |
| Account | | Can't be blank |
| Account | Sixty five | Should be 1 to 12 digits |
| Account | 1234567890123 | Should be 1 to 12 digits |
5. Multi-line step arguments: give your step a table for lunch!
A step can take a multi-line table as an argument. This is a great way to load up a bunch of data or to test the rendering of lists and tables. For instance:
Given I sent "$25" to "mukmuk@example.com" from my "Bank account"
Then I should see the following transaction history:
| create | complete |
| deposit | in_progress |
| transfer | pending |
| withdrawal | pending |
The step definition looks like the following:
Then "I should see the following transaction history:" do |table|
table.raw.each do |event, state|
page.should have_css("tr.#{event}.#{state}")
end
end
I hope that these tips will help you growing healthy cucumber features!
Want more? Check out the Cucumber wiki, 15 Expert Tips for Using Cucumber by Dave Astels, You’re Cuking It Wrong by Elabs and You’re almost cuking it… by Antony Marcano. You could also like (My) RSpec best practices and tips. :)
Happy BDD!
Thanks to Jean-Michel Garnier for reviewing this article.
Entries (RSS)
Follow me on Twitter
Github repos
LinkedIn profile
Photos
Videos
6 Comments
Thanks for this article. It was extremely helpful, as I had no idea step definition could be made up of other step definitions. I’ve got a lot of refactoring to do.
If there are more than 15 features, it’s hard to read (I am lost when I see a list with more than 7 items). We use sub directories which we intend to map with domains of our application ( hard work and long discussions to decide how to group!). Each sub directory has a step_definitions folder and our cucumber.yml has this little erb in order to load them:
default: –format progress features –strict –tags ~@wip –no-source –tags ~@draft -r features/support/env.rb -r features/step_definitions
wordpress ate my code, this should look better:
step_definitions = Dir.glob('features/**/step_definitions/*.rb').map { |file| "-r #{file}" }.join(" ")
default: --format progress features --strict --tags ~@wip --no-source --tags ~@draft -r features/support/env.rb -r features/step_definitions
Yes it definitely helps Philippe! Thanks for these precious tips
Hi,
I am new to cucumber.I am facing the problem while acessing the features .it is showing that StepsDefNotFoundException.how can i solve this problem.can any one please help me regarding this.
Bikash
Bikash,
I am new to this too, but I think the reason is that your step def file is not found. Make sure that your “step_definition” directory is under the features folder.
HTH.
5 Trackbacks
[...] the last few months. Some of my sources of inspiration include: You’re Cuking it Wrong, (My) Cucumber best practices and tips, and You’re Almost Cuking [...]
[...] could also be interested in (My) Cucumber best practices and tips or rspec-set a little gem that helps you speeding up your model specs. . Bookmark the permalink. [...]
[...] BDD by Dan North Cucumber best practices and tips BDD, TDD, Acceptance Testing and Executable Specification Combining TDD/BDD [...]
[...] the last few months. Some of my sources of inspiration include: You’re Cuking it Wrong, (My) Cucumber best practices and tips, and You’re Almost Cuking [...]
[...] to a potentially increased maintainability of the acceptance test constituted by the scenario. This blog post provides examples for how to apply the Gherkin’s reuse capabilities in order to avoid redundancy [...]