[English] Ruby Cucumber: New approach in Ruby testing

Arthur Murauskas

Arthur Murauskas

11 mars 2009 | Catégorie: Posts in English, Ruby, Tutoriél vidéo |

No, I’m not going to talk about cookery or how to cook 10 dishes with cucumbers or any other vegetables, though it could be a perfectly respectable topic :) Instead I will show you a new approach in Ruby testing - Cucumber, which is designed to allow you writing BDD tests on a high level of abstraction (as a plain-text documents).

Lets take look at one of the example features provided with cucumber package:

Feature: Cucumber
  In order to have a happy user base
  As a Cucumber user
  I don't want no stinkin bugs

  Scenario: Reading a table
    Given the following table
      | born  | working |
      | Oslo  | London  |

It doesn’t look like a normal test, isn’t it? Lets play with it a little bit more.

First of all we need to install (I assume that you already have ruby and rubygems packages installed) Cucumber running command:

sudo gem install cucumber mechanize

Create a directory tree for your example project:

mkdir cucumber_test/features/{step_definitions,support}

Now lets write our first scenario, describing search process in Google (I’m taking an idea for this test from Cucumber examples):

Feature: Search
  In order to learn more
  As an information seeker
  I want to find more information

  Scenario: Find what I'm looking for
    Given I am on the "http://google.com" page
    When I search for "drupal magento flex" in form with name "f"
    Then I should see a link to "Adyax :: Drupal Magento Flex Asterisk J2ME web mobile developement ...":http://www.adyax.com/

You’ll need a rake file to run your tests:

require 'rubygems'
require 'cucumber/rake/task'
 
Cucumber::Rake::Task.new do |t|
  t.cucumber_opts = "--format pretty"
end

Lets run it:

$ rake features

If there weren’t any errors then everything is OK; rake told us that we have no scenarios so lets create one. Create a file search.feature in features directory:

Feature: Search
  In order to learn more
  As an information seeker
  I want to find more information

  Scenario: Find what I'm looking for
    Given I am on the "http://google.com" page
    When I search for "drupal magento flex" in form with name "f"
    Then I should see a link to "Adyax :: Drupal Magento Flex Asterisk J2ME web mobile developement ...":http://www.adyax.com/

  Scenario: Find a module
    Given I am on the "http://drupal.org/project/Modules" page
    When I search for "xmlsitemap" in form with method "POST" and action "/project/Modules"
    Then I should see a link to "XML Sitemap":http://drupal.org/project/xmlsitemap

Now you can run “rake features” again:

rake features with no step definitions

Our next task is to create step definitions for our scenario but before we need to prepare our working environment. Create file env.rb in features/support directory:

require 'spec/expectations'
# We are using Mechanize library for navigating through pages
# Alternatively you can use any other library including: watir, webrat, selenium
# Check the full list and documentation here: http://wiki.github.com/aslakhellesoy/cucumber
# Examples of using Cucumber: http://github.com/aslakhellesoy/cucumber/tree/master/examples
require 'mechanize'
 
# before "all"
agent = WWW::Mechanize.new
agent.user_agent_alias = 'Mac Safari'
 
Before do
  @agent = agent
  @page = nil
end

Create file search_step.rb in step_definitions directory:

# These step definitions are far from being ready for common usage
# not depending on the site or page. It's just an example :)
# Parsing arguments with regexp
Given 'I am on the "(.*)" page' do |page|
  # browser goto
  @page = @agent.get(page)
end
 
# Google case
  When /I search for "(.*)" in form with name "(.*)"/ do |query, form_name|
  # search
  @page = @page.form_with(:name => form_name) do |search|
    search.q = query
  end.submit
end
 
# Drupal forms have no name
When /I search for "(.*)" in form with method "POST" and action "(.*)"/ do |query, form_action|
  # search
  @page = @page.form_with(:method => "POST", :action => form_action) do |search|
    search.field_with(:name => 'search_theme_form').value = query
  end.submit
end
 
Then /I should see a link to "(.*)":(.*)/ do |text, url|
  link = @page.link_with(:text => text)
  link.text == text && link.href == url
end

Lets run rake again and see what we will get:
rake features with defined steps

Some more screenshots:

Scenario with misspelled argument

Scenario with misspelled argument

Misspelled argument

Misspelled argument

Of course, our step definitions are far from being common and site-independent but anyhow it wasn’t a goal of this article. Cucumber is a new approach in Ruby BDD which allows to describe behavior of the model with plain-text documents.

To find more examples and documentation visit home page of Cucumber, also check out Redmine plugin StuffToDo which is a nice real-world example of Cucumber usage.



2 commentaires sur “[English] Ruby Cucumber: New approach in Ruby testing”

  1. Evandro dit :

    Arthur, nice tutorial, this helps me so much…
    A litle observation:
    In the rakefile content is missing the world (:features), then the correct must be:

    require ‘rubygems’
    require ‘cucumber/rake/task’

    Cucumber::Rake::Task.new(:features) do |t|
    t.cucumber_opts = “–format pretty”
    end

    • Hi Evandro,

      Thanks for reading our blog. I’m happy that my article is useful :)

      Constructor for class Cucumber::Rake::Task takes 2 arguments: task_name and desc, both have default values. Default value for task_name is “features” (see line 20 in [gem_path]/cucumber/rake/task.rb:

      def initialize(task_name = "features", desc = "Run Features with Cucumber")

      Though, you should define task_name explicitly if you have several tasks. You can find a good example of such case here: http://wiki.github.com/aslakhellesoy/cucumber/using-rake

Laisser une réponse