
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?