Cucumber Makes Behavior-Driven Ruby on Rails Development Cool
by Saurabh Bhatia
March 30, 2010
Using Cucumber can make your Ruby on Rails development projects understandable to the business folks. That's what this Behavior-Driven Development (BDD) tool is all about.
Introduction
This article introduces the Cucumber framework, a tool for implementing the Behavior-Driven Development (BDD) methodology. The idea behind BDD is simple: everyone should understand the system features. Cucumber promotes this idea by enabling the features of a system to be written in the native language of the program as either specs or functional tests.
Although both are Ruby-based BDD frameworks, Cucumber is not a replacement for the popular RSpec framework; they work in conjunction with each other. The major difference between the two lies in the nature of their testing approaches. Cucumber is a high-level testing tool that defines the feature specs, while RSpec is a low-level testing tool that checks for data consistency and application flow.
Although this article is written in the context of Rails, Cucumber has wide applications in other technologies too, from .NET to the iPhone.
Cucumber BDD Use Case
The following diagram breaks down the major components of Cucumber:
Features
|--- Story
|----Scenario ----------| Given , When , Then
|---Steps
Using the example of defining an employee information management system, let's see how each Cucumber component comes into play. First, we need to install Cucumber using this simple command:
eim$ sudo gem install cucumber-rails
[sudo] password for saurabh:
Successfully installed cucumber-rails-0.3.0
1 gem installed
Installing ri documentation for cucumber-rails-0.3.0...
Installing RDoc documentation for cucumber-rails-0.3.0...
When installed, we generate the basic Cucumber tests using the generator script:
Feature defines a functionality of the system, and it is in line with the user Story. User story portrays how the system performs an action via that functionality. We first need to create a feature file with the name feature_name.feature.
eim/features$ nano login_system.feature
Feature: User Login
As a User
I want to Login to the system
So that I can Post a New Employee
We describe the Feature in the Feature: directive, followed by the story. The story is written in the format shown in the code: As a <role> , I want <feature> , So that <business Value>.
Cucumber Scenarios
Every feature has multiple scenarios. Each scenario is a collection of steps, which follow the principal of Given-When-Then:
Given: This section provides the conditions to be fulfilled for the scenario.
When: This section defines what feature does (i.e., the behaviour, the steps).
Then: This section checks the condition after the steps have been followed.
Let's look at how a scenario is written.
Scenario : Login Successful
Given a user that is verified
When I type in the username and password
Then the user Logs in
When the scenario is ready, we issue a command to:
Because we had no steps, we will add some steps to the scenario. The steps that follow will execute one by one:
The RESTful URL (login_path) is called.
The login field is filled with the correct username and the corresponding password.
The login button is pressed and the response expected to pass the test is "Logged In Successfully."
The given step assumes that the user has verified that his/her username is valid to login to the system.
eim/features/step_definitions$ nano login_steps.rb
Given /^user is verified$/ do
pending
end
Then /^the user "(.+)" can log in with password "(.+)"$/ do |username, password|
visit login_path
fill_in "login", :with => username
fill_in "password", :with => password
click_button "Log In"
response.should contain("Logged in Successfully")
end
Hence, a step is a combination of three things:
Given/Then/When directive
A regular expression
A block of Ruby code that describes the step
The text in each step is matched against the regular expression of the corresponding step to find out which is going to be used. When the appropriate match is found, the regular expressions are used to match the block of Ruby code being used.
Conclusion
Cucumber is good for writing functional tests and feature specs. The business analyst can write features and scenarios in English in Cucumber format, whereas the developer can write code and tests to make the scenarios and steps run appropriately.
About the Author
Saurabh Bhatia has been working with Rails since early 2006 and has a startup company, Safew Labs, that offers Rails consulting. He likes to write clean code, read and write.