Cucumber Logo

In this post I'm going to attempt to document some useful guidelines that in my experience has lead to writing cleaner, more maintainable and less flaky features.

Features can contain extra details if it is relevant to the feature

Lets say we are requesting some data from a rest service and we are expecting an xml response. It may be useful for documentation purposes to show this xml response right in the feature file.

Scenario: Data Request
Given I request some data from http://sample.org/data.xml
I should see the xml
'''
<xml>
  <data>
    hello
  </data>
</xml>
'''

Scenarios should not automate the UI

Consider the following code:

Scenario: Invalid email address
When I fill in "Username" with "Username"
And I fill in "Password" with "password123"
And I fill in "Confirm Password" with "password123"
And I fill in "Email Address" with "invalid email address"
And click "Create User"
Then I should see "Please enter a valid email address"

There is a lot of code here that is not relevant to the scenario at all and only serves to automate the browser.

If we remove the details that aren't relevant we get a much more readable scenario:

Scenario: Invalid email address
When I fill in an invalid email address
And click "Create User"
Then I should see "Please enter a valid email address"

Features should only contain information that the user sees

Element ids, CSS and XPath is only relevant to developers and should be kept in the step definitions or removed entirely.

In the following code example we use Capybara to fill in the password text input using the label which links to it using the 'for' attribute.

<label for="password">Password</label>
<input type="text" name="password">
fill_in "Password", :with => "password123"

If you are using SpecFlow instead of Cucumber then Coypu is a very powerful Capybara-like .NET tool.

Scenarios should not be dependant on other scenarios

There should never be a situation where one scenario needs to be run before another scenario.

I've personally seen feature files that had scenarios with names that had number prefixes in order to make sure that they ran in a certain order. This is evil and should never happen.

Never ever ever let this happen:

Scenario: 0TestSetup
  Given some data is in the database

Scenario: 1UserNavigatesToProfilePage
  Given the user has logged in
  When I click Profile
  Then I should see the Profile page

Scenario: 2UserChangesTheirPassword
  When I enter a new password
  And I click Save
  Then I should see "Password changed"

Use Background for setup when there's more than one scenario

Remember that whatever is more readable is always better. In the first code sample we only have one scenario so we don't need to DRY up the feature yet, but in the second sample it makes sense to add a Background section.

Scenario: Logged in user visits the user registration page
  Given I am logged in
  And I visit the user registration page
  Then I should be redirected to the home page
Background:
  Given I am logged in

Scenario: Logged in user visits the user registration page
  And I visit the user registration page
  Then I should be redirected to the home page

Scenario: Logged in user visits the logout page
  And I visit the logout page
  Then I should be redirected to the home page

Feature names are features not processes

Feature names should describe actual features. An example of a bad feature name is "A user registers an account". This feature should probably be called "Registration" or "User Registration".

Don't use multiple 'thens'

Instead of multiple Thens use one Then and follow it up with Ands. The second scenario below is a lot more readable.

Scenario: Registration
  When I fill in user details
  And click Register
  Then I should be redirected to the home page
  Then I should see "account created"
Scenario: Registration
  When I fill in user details
  And click Register
  Then I should be redirected to the home page
  And I should see "account created"

Your features are your documentation

Relish is a very useful new site that takes all your feature files and displays them in a very readable format.

Why not push all your features up there so that anyone in your team can have access to your feature documentation?

Relish feature