May 12

Cucumber allow us to describe behavior in plain text. Because the text is written in a business-readable domain-specific language, beside serves as automated tests and development-aid, it also can be used as documentation. In this post we’re going to create a Rails application from scratch, and use Cucumber to define its behaviour.


Install Cucumber, Webrat and RSpec

If you’re happen to be a Ubuntu/Debian user then you need to install Nokogiri first. Nokogiri is an HTML, XML, SAX, and Reader parser. We’re gonna use Webrat in the Step Definition, so we’ll have to use have it installed too.gem install rspec rspec-rails cucumber webratsatisfy plugin dependencies

gem install term-ansicolor treetop diff-lcs nokogiri builder

Creating The Application

We’ll start by creating a new Rails application and for the purposes of this example we’re going to use the classic example and create a todos list app. To start we’ll create the application in the usual way:

rails todos

and create the corresponding databases. Now go to your application directory and set up Cucumber with

ruby script/generate cucumber

command you just entered will generate a features directory under your application’s root directory and it’s here where we’ll define our application’s behavior.

Creating a Feature

We are creating a todos list application in order to manage our never ending todos list, so let’s create a file called manage_todos.feature in the features directory.

Feature: Manage Todos  In order to make a todos listAs an userI want to create and manage todos

Now still on the same file, we’ll define some of the feature’s behaviour by writing one (or more scenario)

Scenario: Todos List  Given I have todos titled Breakfast, Go to the Office  When I go to the todos list  Then I should see "Breakfast"  And I should see "Go to the Office"

now you can run Cucumber with

cucumber features/manage_todos.feature -n

You’ll see from the results of running the scenario, 3 of the steps were skipped and on is marked as undefined. Now let’s write the Ruby code to implement it.

Step Definitions

Create a file called todos_steps.rb in the features/step_definitions directory, this is where we’ll define our scenario. The scenario

Given I have todos titled Breakfast, Go to the Office

will implement this step definition

Given /^I have todos titled (.+)$/ do |titles|  titles.split(', ').each do |title|    Todo.create(:title => title)  endend

after adding the above code to todos_steps.rb, try to run Cucumber again and watch it fail because the we don’t have a Todo model. Now let’s code the Todo model and since we’re using RSpec, we’re gonna use RSpec generator to create it

ruby script/generate rspec_model Todo title:string is_done:boolean

and run the migration. Now run Cucumber again and you will see that we passed the first step but the second is fail. Let’s create the path of “the todos list” by adding

when /the todos list/   todos_path

in the features/support/paths.rb then add this in file routes.rb

map.resources :todos

when you run Cucumber at this point, you will see error message:

uninitialized constant TodosController (NameError)

Now let’s create the controller

ruby script/generate rspec_controller todos index

when you run Cucumber again, you will see that Cucumber isn’t satisfied enough, it expects to see “Breakfast”. Let’s open the controller and make sure it now show the todos list

def index   @todos = Todo.all end

and for the viewNow run the Cucumber again then you will see all the steps passed.

Selenium integrated with Webrat

We are going to integrate Selenium with Webrat. We’ll start with installing Selenium gem

sudo gem install selenium

Now to  install Selenium Remote you must download selenium-remote-control first from http://selenium.org/download. Extract and find selenium-jar then copy the file to GEM_INSTALL_DIR/Selenium-1.1.14/lib/selenium/openqa/ and rename it to selenium-server.jar.txtIf you happen to use Ubuntu you have create a sym link due to a bug with Selenium and Firefox 3

sudo ln -s /usr/lib/firefox-3.0.9/firefox /usr/bin/firefox-bin

Now you can start Selenium with

selenium

We can start to make Cucumber / Selenium / Webrat to be integrated.  It’s done because many apps have features that don’t require javascript to work, and running them all in selenium makes things slow. Here the solutions :

  • Run your non-selenium features with transactional fixtures and standard Webrat steps
  • Run your entire suite (html and javascript) features with selenium, without transactional fixtures
  • Reuse all (or almost all) or your step definitions between selenium and non-selenium runners

First, setup a directory structure like this you will have the following in the features directory

.|-- enchanced |-- manage_todos.feature |-- plain |-- step_definitions |   |-- todos_steps.rb |   `-- webrat_steps.rb `-- support |-- env.rb `-- paths.rb

then create a cucumber.yml with 2 profiles in your application root directory thet contains

default: -r features/support/env.rb -r features/support/plain.rb -r features/step_definitions features/plainselenium: -r features/support/env.rb -r features/support/enhanced.rb -r features/step_definitions features/enhanced

turn on all webrat features in env.rb

ENV["RAILS_ENV"] = "test"  require File.expand_path(File.dirname(__FILE__) + '/../../config/environment')require 'cucumber/rails/world'require 'cucumber/formatters/unicode'require 'webrat/rails'require 'cucumber/rails/rspec'

then in plain.rb we set up the standard Webrat features

Cucumber::Rails.use_transactional_fixtures

now try to run you Selenium features with

cucmber -p selenium

Using fixtures in cucumber

To use fixtures in cucumber, first you want to add the following to env.rb

Before do  Fixtures.reset_cachefixtures_folder = File.join(RAILS_ROOT, 'spec', 'fixtures')  fixtures = Dir[File.join(fixtures_folder, '*.yml')].map {|f| File.basename(f, '.yml') }  Fixtures.create_fixtures(fixtures_folder, fixtures)end

create fixture files in directory /spec/fixtures/

spec/|-- fixtures|  `-- todos.yml

you easily use fixture using Model.find(). Lets add some todos to todos.yml

one:  title: Go home  is_done: falsetwo:  title: Get some sleep  is_done: false

Then add this following scenario to manage_todos.feature

Scenario: Todos List from fixture  Given I have some todos  When I go to the todos list  Then I should see "Go home"  And I should see "Get some sleep"

and for todos_steps.rb we add this

Given /^I have some todos$/ do  Todo.find(:all)end

You can now run cucumber and see your test passed.Well that’s folks, since this post covered only the basics of Cucumber but we hope it is enough for you to get started with.

Leave a Reply

Security Code: