Cucumber Best Practices
cucumber is a BDD(Behaviour driver development) framework. Basically test cases are written in plain text which is called Gherkin language, just in Given-When-Then steps. After that, developer will write implementation for those steps.
It’s good to bridge the communication between business requirement and implementation. The ideal work flow would be business analysis or QA write features and developer implements them. However, in a real world, developer write both of them. Cucumber is different programming model than what we normmaly use like Java, ruby, etc. It is not mature enough like OO which has tons of patterns and best practices to apply.
Below are some best practices when I use cucumber for one project.
Write declarative features
Scenarios should be written like a user would describe them.
Beware of scenarios that only describe clicking links and filling in form fields, or of steps that contain code or CSS selectors. This is just another variant of programming, but certainly not a feature description.
Bad
Scenario: Adding a todo item
Given I have a todo list named "Mondays list"
When I go to the home page
And I fill in "username" with "dave"
And I fill in "password" with "secret"
And I press "Log In"
And I go to the todo page
And I click on link "Mondays list"
And I fill in "todo" with "Grab some milk"
And I press "Add todo"
Then I should see "Todo item added successfully"
Good
Scenario: Adding a todo item
Given I have a todo list
And I am logged in as a normal user
When I add a todo item
Then It should be added to the todo list
Use As a <role>, I want <goal/desire> So that <benefit>
format for feature description
Describe feature in user story style. Starts the feature and gives it a title, then follow with user story format.
Bad
Feature: Create an account
Scenario: ...
Good
Feature: Create an account
As a user
I want to create an account for me
So that I can re-login to the same account
Scenario: ...
Use should
in each Then
and following And
steps
The purpose of Then
steps is to observe outcomes and verify result. Using should
word as a convention makes it easy to understand, and make sure do verification in implementation step.
Bad
Then My job is displayed in the table
*Good
Then My job should be displayed in the table
Capitalize first letter of every step
Each step is independant, capitalize first letter makes a nice format.
Bad
Then my job should be displayed in the table
Good
Then My job should be displayed in the table
Use page object model
Don’t write implementation in step definition, use page object model.
Bad
When(/^I search for my job$/) do
visit path_to('manage jobs')
find('a', :text => 'Filter Jobs').click
fill_in('users-id-search', :with=>"")
page.find('#users-id-search').native.send_keys(:backspace)
fill_in('requisition.title', :with => @job.title)
click_button('Search')
end
Good
job_steps.rb
When(/^I search for my job$/) do
@app.manage_job_page.load
@app.manage_job_page.search @job.title
end
manage_job_page.rb
def search(job_title)
find('a', :text => 'Filter Jobs').click
fill_in('users-id-search', :with=>"")
page.find('#users-id-search').native.send_keys(:backspace)
fill_in('requisition.title', :with => @job.title)
click_button('Search')
end
Use background
If all the scenario in one feature file have the same steps, put them in the background.
Bad
Scenario: Foo
Given I am logged in as an admin
And ....
Scenario: Bar
Given I am logged in as an admin
And ....
Good
Background:
Given I am logged in as an admin
Scenario: Foo
Given ....
Scenario: Bar
Given ....
Use Tags
Tags are a great way to organise your features and scenarios.
Good
@job @smoke
Feature: Job management
Avoid to use step params
Step params is a smell which the feature is not declarative.
The parameter in feature should not be used as implementation parameter.
Bad
Given I complete registration from using email "test@example.com"
Good
Given I complete registration form using a valid email
Avoid to use scenario outlines
A Scenario Outline provides a parametrized scenario script. However, it easily become an anti-pattern if you use it too many.
Each scenario with example actually means a different scenario. It’s better to use scenario with a meaningful name instead of using scenario example.
Scenario outlines uses step params, which should avoid to use.
Beware of feature that only has one scenario but have a long list of examples. It could be a smell that too many different scenario are put together.
Avoid to use data tables
Data tables provides data for implementation. It is against the rule of feature should be declarative and business focus.
Feature should not provide any detail implementation or data for testing.
Use Capybara find
whenever possible
find
will wait for a set amount of time and continuously retry finding the element until either the element is found or the time expires.
Bad
first(".active").click
Good
find(".active", match: :first).click