Update (13th Jume 2012): This is an old, old post that still gets a lot of hits. I don’t recommend this practice anymore. Instead, I recommend composing Ruby methods that carry out these actions. For more details, please see The Cucumber Book.
A while back, I asked the Cucumber team for the ability to call in the steps of one scenario from another.
The canonical example of this is the ‘log in’ scenario:
Scenario: User logs in
Given there is a User whose username is "matt"
And I follow "log in"
And I enter "matt" in "username"
And I enter the User's password in "password"
And I press "Log In"
Then I should be logged in
And I should see the text "Hello matt"
Phew. Now obviously I don’t want all this noise in the scenario every time I specify behaviour that requires a logged in user. I want to write something like this:
Scenario: User views their dashboard
Given I am logged in
And I follow the "dashboard" link
Then I should see "This is your dashboard"
Thanks to the fabulous creativity of the Cucumber community, this is now possible. It’s also highly recommended, as it’s a great way to help you keep your step files tidy and DRY of excess duplication.
Given /I am logged in/ do
steps %{
Given there is a User
When I follow "log in"
And I enter "#{User.first.username}" in "username"
And I enter "#{User.first.password}" in "password"
And I press "Log In"
}
end
I’m doing this more and more now – writing simple ‘building block’ steps and assembling them to make steps that read nicely and make sense to the stakeholders.
When I have lots of quotes, I prefer this:
Given %{I enter “#{User.first.username}” in “username”}
You just put some extra shine on my Ruby! Thanks Aslak 🙂
i know this thread is old but what about scenarios that require reuse of a set of data. My example is a set of flights. I have several scenarios for delaying, canceling, or other scheduling based actions that all need a set of flights over time that are affected by the actions. I would like to define this set in one place and reuse them in the different scenarios probably using a Background: type given scenario. Is there a way to do this or a better suggestion for handling this?
Hi Wes,
It definitely sounds like Background would fit well for you – you can set up the data in the background then carry out different actions on it in different scenarios. The advantage of doing this is your tests are very clear about the data being set up. The disadvantage is that you can’t vary that data at all in the different scenarios. Spelling out the data to use can also be a bit noisy – sometimes the specific data you use doesn’t matter – you just want the general sense of the state of the system.
See this excellent post by Ben Mabey on that subject.
Thanks a lot, very useful.
A must have if your serious about testing
I was trying to find your article using “cucumber nested given” on google which didn’t work.
So I thought i’d add the keywords in the comment.
Thanks for the post, I was in the same place of reusing steps for testing user authentication with authlogic.
I am working on a legacy application with an old cucumber version. From what version does Cucumber support nested steps?
@Jairo: according to https://github.com/cucumber/cucumber/blob/master/History.md it was first added in v0.1.7
Yes reusing Gherkin steps in the step definitions was a huge progress. However I really miss the matching feature in Gherkin space. RSpec has its Shared Examples feature and I have always wondered why the Cucumber team never wanted to augment Gherkin to allow a better behaviour factoring.
Isolating the stakeholders from the programming language is one of the main justification of Cucumber so why are we forced to enter the step definition space to get a nice feature like nested specifications ?
An example is here: https://gist.github.com/1084580
I agree Arnaud, it would be better if these mappings were surfaced in Gherkin. However it’s not easy to do technically, so it’s hasn’t been implemented yet. I hope it will happen eventually, but we might have to wait for Cucumber 2.0!
Thanks for the info!
Just a quick update: using ‘given’ and ‘when’ as part of a step definition is now deprecated, and the cucumber team wants you to use ‘step’ instead (according to my console output).