11th May, 2012 14 Comments
My primary reason for using Cucumber in a recent automation initiative was to try and bridge a technology-business divide that existed in my workplace by giving the non-technical stakeholders a larger sense of involvement in testing with a (longer term) view to them actively contributing to future test specs by using the plain English approach that Cucumber does so well.
However, when I first started looking into Cucumber, there were a multitude of references out there but as I was also learning about Ruby, Watir and RSpec at the same time it became a little difficult to see the wood for the trees because they tended to talk about all of these things without being clear about where one thing stopped and another began.
What I’d like to do with this post is present a simple Cucumber 101 tutorial, letting cucumber guide us through the creation of a set of ‘scenarios’ (this is what Cucumber calls ‘tests’ or to be more precise, ‘checks’ – this is automated after all).
1. Cucumber Basics
Cucumber is a command line tool and when you run it, it looks for plain-language text files which typically contain one or more features, and within each feature, one or more scenarios to test. Within each scenario you have a number of steps that Cucumber works through. There is some syntax involved so that cucumber can understand what you’ve written and this is known as Gherkin. I’ll highlight this in the examples below.
So if you were to see the directory structure required for a simple cucumber project, it would look something like this:
2. Installation Prerequisites
This tutorial assumes you have a copy of ruby, rubygems (or equivalent), watir-webdriver, rspec and of course cucumber installed on your target system.
3. Create a Scenario
Let’s create a new Cucumber project (a directory, called ‘Cuke’) and try running cucumber in this empty directory.
Wait, how do we run cucumber? Simple, type ‘cucumber’ (Note: We can specify arguments but in the absence of any cucumber assumes you want to run everything – more on that later).
So we have no features or scenarios. Cucumber is looking for a features directory. Let’s create one as it suggests. Once we’ve done that, let’s try running cucumber again.
So now we see that although cucumber found a features directory, there were no feature files and consequently no scenarios to run, hence the “0 scenarios” and “0 steps” references.
Let’s create a scenario in a feature file under the features directory, and let’s call the feature file karate.feature. Here’s the content:
For those of you unfamiliar with karate, Hironori Ohtsuka was the founder of the Wado-Ryu style of karate, and our scenario is checking for the presence of the founder’s surname in the Google results on a search for ‘Wado’.
You can see the Gherkin grammar highlighted in blue above – these must be used when writing feature files – the key Gherkin words include – Feature, Background, Scenario, Scenario Outline, Scenarios (or Examples), Given, When, Then, And (or But) and a couple of other symbols.
Now let’s run cucumber again with the new feature file in place:
So, cucumber is now picking up our new feature file. Great!
However, all of our scenario steps are as yet undefined.
4. Add Step Definitions
So, two things about the above output. Cucumber is telling us that our steps and scenario are as yet undefined (the yellow text) and that as yet, it doesn’t know which programming language we intend to use to implement our scenarios (the red text). Let’s take our lead from Cucumber and copy the suggested steps into a new step definition file, say step_karate.rb (The .rb suffix indicates a Ruby file). Like so…
and run cucumber again
You may notice that the red text we saw in the ‘undefined’ error above has now gone. Why? We’ve put a Ruby (.rb) step definition file in place so Cucumber now knows we’re intending to use ruby to implement the scenario. So now we can map all the steps in our scenario to a step definition file, and cucumber helpfully provides the file and line number of each step it finds (this comes in useful later when you have large suites of scenarios) You’ll also notice that Cucumber has deemed the first step as ‘pending‘ (I.e. to be implemented) – this is due to the pending statement in the step definition. This acts as a placeholder so you can write some proper code for each step when you are ready. Cucumber takes a sequential approach to scenario steps and the subsequent steps are deemed ‘skipped‘
5. Implement Step Definitions
Let’s implement our first step definition now. We’ll take out the pending statement and put in some Ruby code that will start a web-browser.
So for our first step “I navigate to Google” we’ve removed the pending statement and inserted two lines of Ruby/Watir-Webdriver, to start a browser (Firefox) and to navigate to Google.
Note: I’ve included a Ruby ‘require’ statement in the step definition file. There are tidier ways of doing this since the key to maintainability of any cucumber suite lies with the step definition files. We’ll tidy this up a bit later
Let’s run cucumber again
Now we see the first step passes (green), the second step is pending (yellow), and the third step is skipped (blue). Progress! You’ll also notice a browser opened in front of you (at Google) that hasn’t been closed – that’s because we didn’t close it in our code (yet). For now, kill the browser – we’ll tidy that up later. Let’s implement the remaining steps as shown below:
In the second step, we create variables for the Google search field and button, then enter the value ‘Wado’ into the search field and click on the button. In the third step we check that the results page has loaded and then perform another check to see if the text ‘Ohtsuka’ is present in the results page. If it’s there, the step will pass, and if it’s not the step will fail. Lastly, we close the browser instance.
6. Passed & Failed Scenarios
7. Tidy Up – Environment, Hooks, etc
First of all, let’s get rid of that ‘require’ statement in the step definition file and put it somewhere more appropriate. We’ll create a new directory under features, called support, and under there we’ll create an environment file, env.rb and add two lines
8. HTML Formatters
You can also direct cucumber output to an HTML file using the default HTML formatters. by running the command:
cucumber -f html >output.html
So as you can see the failed step is highlighted in red, as is the scenario, as is the cucumber header (if one scenario out of many fail then the header is coloured red accordingly).
Now let’s change the string ‘Octavias’ back to ‘Ohtsuka’ and re-run
9. Multiple (Similar) Scenarios – Placeholders
- Wado-Ryu (Hironori Ohtsuka)
- Shotokan (Gichin Funakoshi)
- Goju-Ryu (Chojun Miyagi)
- Kyokushinkai (Masutatsu Oyama)
cucumber -t <tag>
- cucumber -t @all (This would run everything – all four scenarios)
- cucumber -t @daily (This would run the top two scenarios for Wado and Shotokan)
- cucumber -t @monthly (This would run the bottom two scenarios for Goju and Kyokushinkai)
- cucumber -t @wado (This would only run the top scenarios for Wado)