Vita Rara: A Life Uncommon

Testing Non-Ruby Applications with Cucumber


Categories: | | | | |

Yesterday we got Cucumber working to test an older J2EE application that uses EJB 2.1 for its persistence layer. This application because of the J2EE EJB 2.1 beans has been very hard to near impossible to test in the past. I've been hearing about Cucumber for a while and we decided it was time to take a deeper look.

We plan on adding new features to this application using Rails, and over time porting the existing functionality to Rails. So, having a test suite written in Ruby that can test the application regardless of the underlying implementation was necessary. Cucumber with Webrat to the rescue. The general outline below will work with web applications written in any language. All of the interaction with the application happens at the HTTP protocol level.

To do this I assume you have some level of familiarity with Ruby and have a working Ruby and Rails environment on your system.

First install Cucumber, Mechanize, and Webrat. Now you need to patch Webrat's support for Mechanize (pull request sent to the author of Webrat). From the root of where gems are stored on your system you'll need to edit /webrat-0.4.2/lib/webrat/mechanize.rb. Change line 39 from:

@mechanize = WWW::Mechanize.new

To:

@mechanize ||= WWW::Mechanize.new

In my Java project I created a new Rails project. In my case this was in $PROJECT_ROOT/src/.

% cd src
% rails rails

This creates a Rails project named rails in the Java project. I did this because I intend to add new features using this Rails project to the working Java application. I also plan on integrating Factory Girl into to manufacture the fixtures needed to run our Cucumber specs.

In the Rails project run 'ruby ./script/generate cucumber'. This will create a number of directories and files in features and adds a Cucumber Rake task. Now we need to configure Cucumber to use Webrat's Mechanize support. Look for a block similar to this and set the Webrat config.mode to :mechanize.

Webrat.configure do |config|
  config.mode = :mechanize
end

Then configure the Cucumber world to use the Mechanize support:

class MechanizeWorld < Webrat::MechanizeSession
  require 'spec'
  include Spec::Matchers
end

World do
  MechanizeWorld.new
end

With that in place you should be able to write features and step definitions in Cucumber that access your Java web application, or a web application written in any language for that matter.

Mechanize and Webrat compatibility

(...apologies for reposting...forgot to fix the error msg for angle brackets)

Thanks for this helpful post! I've been able to use it to start automating regression testing for a non-Ruby webapp. I'm having some trouble with the "contains" method, as, for example, used in my webrat_steps.rb file:

Then /^I should see "([^\"]*)"$/ do |text|
response.should contain(text)
end

The error I get is:

undefined method `contain' for #<MechanizeWorld:0xb70a4ff8> (NoMethodError)

Do you know if there is some Mechanize method that might do what "contain" does? (if I understand this error correctly), or some other workaround?

RSpec

The only question that comes to mind is if you have RSpec installed?

Mark

I am having the same

I am having the same problem

I have Webrat, Mechanize, Cucumber and Rspec installed from their latest gems, but MechanizeWorld can't find contain. I'm assuming I'm missing an include somewhere, but I'll be damned if I can figure out where.

Figured it out. I added the

Figured it out. I added the following two lines to env.rb, and now the contain matcher works
include Webrat::Methods
include Webrat::Matchers

Mechanize and Webrat compatibility

Thanks for this helpful post! I've been able to use it to start automating regression testing for a non-Ruby webapp. I'm having some trouble with the "contains" method, as, for example, used in my webrat_steps.rb file:

Then /^I should see "([^\"]*)"$/ do |text|
response.should contain(text)
end

The error I get is:

undefined method `contain' for # (NoMethodError)

Do you know if there is some Mechanize method that might do what "contain" does? (if I understand this error correctly), or some other workaround?