Articles

Apply Behavior Driven Development to Ruby on Rails with RspecApply Behavior Driven Development to Ruby on Rails with Rspec

Introduction

Applying the Behavior Driven Development (BDD) methodology with a Ruby-based BDD framework allows developers to write system requirements in a Ruby format first and then write Ruby code for the particular features of those requirements. Because the Ruby format is similar to plain English, business analysts and the people gathering the requirements can participate in the development process.

BDD mandates that developers write tests for each step of the process, which leads to cleaner code. The BDD process begins with the development team creating a scenario, for which they describe each feature. The initial scenario inevitably fails. The team subsequently defines each step (iterative test) and writes the application code for each feature. They also refactor the code when the scenario passes each step.

A few different Ruby-based BDD frameworks are available. RSpec, Cucumber, and Shoulda are the most popular. Let's see how RSpec works by using the use case of an employee information manager.

Installing RSpec and Creating Required Directories

The installation of RSpec is pretty straightforward. I just use the gem install command on the command line.

saurabh@home:~$ sudo gem install rspec
[sudo] password for saurabh:
**************************************************
Thank you for installing rspec-1.2.9
Please be sure to read History.rdoc and Upgrade.rdoc
for useful information about this release.
**************************************************
Successfully installed rspec-1.2.9
1 gem installed
Installing ri documentation for rspec-1.2.9...
Installing RDoc documentation for rspec-1.2.9...

Next, I make RSpec locally available to my Rails application and add it as a plugin to my Rails. When I run this installation, the RSpec-Rails plugin will be installed within the Vendor directory of the Rails application.

saurabh@home:/media/S3A6128D005/Users/ongc/eim$ script/plugin install git://github.com/dchelimsky/rspec-rails.git
Initialized empty Git repository in /media/S3A6128D005/Users/ongc/eim/vendor/plugins/rspec-rails/.git/
remote: Counting objects: 218, done.
remote: Compressing objects: 100% (176/176), done.
remote: Total 218 (delta 15), reused 129 (delta 3)
Receiving objects: 100% (218/218), 87.67 KiB | 93 KiB/s, done.
Resolving deltas: 100% (15/15), done.
From git://github.com/dchelimsky/rspec-rails
* branch            HEAD       -> FETCH_HEAD

After installation, I am ready to create the directories required for spec with the following command:

saurabh@home:/media/S3A6128D005/Users/ongc/eim$ ruby script/generate rspec
Configuring rspec and rspec-rails gems in config/environments/test.rb ...
exists  lib/tasks
create  lib/tasks/rspec.rake
create  script/autospec
create  script/spec
create  spec
create  spec/rcov.opts
create  spec/spec.opts
create  spec/spec_helper.rb

Applying BDD with RSpec

Now, let's take on the scenario of collecting employee information and define it using RSpec according to the BDD process. While collecting employee details, we will also collect information regarding their interests and hobbies. So, here is how we present the scenario:

  • User goes to the hobby page.
  • User enters a list of sports he/she likes.
  • The user cannot leave any box blank.

Now that we have a description of the scenario, we can start writing the model specs. Before that, however, we need to create the skeleton code for the model spec.

saurabh@home:/media/S3A6128D005/Users/ongc/eim$ script/generate rspec_model Hobby
exists  app/models/
create  spec/models/
create  spec/fixtures/
create  app/models/hobby.rb
create  spec/models/hobby_spec.rb
create  spec/fixtures/hobbies.yml
exists  db/migrate
create  db/migrate/20100112073803_create_hobbies.rb

BDD helps to create context for the scenarios. Here's how our feature specification for hobbies looks like.

         context "A user " do
setup do
@hobby = Hobby.new
end 
specify "should be invalid without all boxes filled"
@hobby.should_not_be_valid
@hobby.sports = "sportname"
@hobby.should_be_valid
end
end

Now, we need to write the code for this feature in order to make it pass. In order to do so, we require a hobby model and table. We add the tables using migrations.

class CreateHobbies < ActiveRecord::Migration
def self.up
create_table :hobbies do |t|
t.column :sports, :string
t.timestamps
end
end
def self.down
drop_table :hobbies
end
end

When we look at our specs, we see that the sports field is a mandatory. Hence, we need to add a validation in the Hobby Model.

class Hobby < ActiveRecord::Base
validates_presence_of :sports
end

In order to run the tests, we need to create the test database and set up the test environment correctly. After that, we can run the spec we just defined.

saurabh@home:/media/S3A6128D005/Users/ongc/eim/spec/models$ spec hobby_spec.rb
F
1)
ActiveRecord::RecordInvalid in 'Hobby should create a new instance given valid attributes'
Validation failed: Sports can't be blank
./hobby_spec.rb:11:
Finished in 0.03787 seconds
1 example, 1 failure

The test fails because the Validation says sports can't be blank. Voila! We've done it; the validations are running. Let's add some data and pass the values to the test. We will run them again when the data is specified and see if they pass or not.

Data is passed in RSpec through the spec_helper. In this case, the test data needs to be a value for sports. So, we use spec_helper to pass the value of our sport through to the spec under the valid_attribute specification.

require 'spec_helper'
describe Hobby do
before(:each) do
@valid_attributes = {
:sports => 'soccer'
}
end
it "should create a new instance given valid attributes" do
Hobby.create!(@valid_attributes)
end
end

Now, we run the spec tests again and check.

saurabh@home:/media/S3A6128D005/Users/ongc/eim/spec/models$ spec hobby_spec.rb
.
Finished in 0.189719 seconds
1 example, 0 failures

The test passed! We have just finished writing a feature using RSpec.

Conclusion

Behavior Driven Development is an effective methodology that reduces the time required for requirements gathering, because business analysts write their specs in the rspec format and developers can write code to meet that specification. It also introduces better discipline and control over tests.

 

Original Article


Website Design | Website Development | Flash animation | Flex applications | Logo Design | Mobile Applications Development | iPhone | iPad | Google Android

Content Management Systems | E-Commerce | Social Networking | Dating Websites | Membership Websites | Zend Framework | PRADO | Symfony | Wordpress

ASP.NET | PHP | C# | Objective-C | AJAX | Web 2.0 | HTML | CSS | Javascript | MySQL | MSSQL

 


Host unlimited domains + get up to 5 FREE domains with your 1&1 hosting account. Must see monthly hosting specials!


Invite your friends to Stable Flow

Enter up to 3 email addresses of your friends: