feature: <short description>
<full description>
background:
scenario:
...
scenario outline:
examples:
...
The feature file starts with a description of the feature. The format of the description is free, but usually e.g. following template is used:
In order to ...
as a ...
I need to ...
For example:
Feature: Application sign-in
In order to sign in
as an end user
I need to enter valid credentials
After the description comes the background. The background contains the preconditions for all scenarios. The format of the background is similar to the format of the scenarios, but the only difference is that the steps in the background will be executed before each scenario. It could for example, be like this:
Background:
Given a registered user
Then comes the scenarios or scenario outlines. A scenario is like one test case. A scenario is made up of three steps: Given, When and Then.
Given is the precondition for the test case.
When is the action to be taken.
Then is the verification / what should happen.
For example:
Scenario: Successful sign-in
Given sign-in page to the application
When I enter valid credentials
And click on the sign-in button
Then I'm successfully logged in
But no error text should be displayed
Notice that And or But can be given in any of these three steps.
The other possibility is to use a scenario outline. It could look like this:
Scenario outline: Application sign-in
Given sign-in page to the application
When I enter username <username> and password <password>
And click on the sign-in button
Then I'm <loginstatus> logged in
Examples:
| username | password | loginstatus |
| validuser | validpwd | successfully |
| invaliduser | validpwd | not |
| validuser | invalidpwd | not |
When running the feature, the scenario will be repeated with the values in each row in the examples table. So in this case the scenario will be repeated four times.
You could also have many examples tables for one scenario outline e.g.
Examples: Successful logins
| username | password | loginstatus |
| validuser | validpwd | successfully |
Examples: Failed logins
| username | password | loginstatus |
| invaliduser | validpwd | not |
| validuser | invalidpwd | not |
Now if you save your feature file and run it, you will get an output similar to this:
1 scenario (1 undefined)
5 steps (5 undefined)
You can implement step definitions for undefined steps with these snippets:
Given /^sign-in page to the application$/ do
pending
end
When /^I enter username validuser and password validpwd$/ do
pending
end
When /^I enter username invaliduser and password validpwd$/ do
pending
end
...
This tells that there are five missing step definitions i.e. you need to have matching step definitions for each line in the feature file in your step definition file. To get started with your step definitions file, copy the above pending step definitions to your step definitions file. The next thing I would do is to combine / group step definitions. As you can notice the step definitions:
When /^I enter username validuser and password validpwd$/ do
pending
end
When /^I enter username invaliduser and password validpwd$/ do
pending
end
... are very close to each other. They could be combined to one step definition:
When /^I enter username (.*) and password (.*)$/ do |user,pwd|
end
After this you need to insert the actual test script code in each step definition. It is also possible to call another step definition from within a step definition e.g.
When /^I enter username (.*) and password (.*)$/ do |user,pwd|
step "I enter valid credentials"
end
There are still a couple of things that you need to / is good to know - tags and hooks!
Tags
In your feature file you can add tags. Tags are strings starting with @ e.g.
@highpriority
Scenario: ...
If you now wan't to run all scenarios tagged with @highpriority, you can do it like this:
cucumber --tags @highpriority
If you wan't to run all scenarios, except those ones tagged with @highpriority:
cucumber --tags ~@highpriority
Hooks
With the help of hooks you can run some specific script code in different places during the test runs. There are many predefined hooks available in Cucumber. Hooks are defined in files in the support folder, usually env.rb or hooks.rb.
To do something before starting to run any scenario, put that code at the top of the file. To do something when the run ends, use the at_exit hook. To run some code before or after a scenario, use the Before or After hooks. You can also execute some specific code after each step with the AfterStep hook. It is also possible to run different code if scenario passes or fails:
Before do
# Do something before each scenario
end
After do |scenario|
if(scenario.failed?)
# Do something if scenario failed
end
if(scenario.passed?)
# Do something if scenario passed
end
end
Then there is also possibility to use tagged hooks i.e. just execute some code for tagged scenarios. For example.
After('@highpriority', '@mediumpriority') do
# Do something after scenarios tagged with @highpriority OR @mediumpriority
end
Before('@highpriority, @mediumpriority') do
# Do something before scenarios tagged with @highpriority AND @mediumpriority
end