Resident Demigod

Veezus Kreist

Divine missives

Integration testing without cucumber

September 12, 2009 02:38

There are three main testing cliques at Hashrocket: the Fakirs, the Derivatives, and Team Zombie. Fakirs are so named because they stub and mock everything – making it all fake. Derivatives are the exact opposite, preferring to forego unit testing in most cases and just write integration tests that interact with the code through a browser. Team Zombie (the “decomposers”) had just the right mix for me: integration testing for core business value, unit testing individual methods, and stubbing them elsewhere. Personally, such a technique helped me with my data models: too many stubs means too complex a model.

Additionally, I’ve never been in love with cucumber; the regexes drive me crazy, and I’ve never had a client who wants the (admittedly very nice) story formatting that it gives. I’ve been working on a green-field app this week at Hashrocket for the first time in months and it’s given me an opportunity to try out a new integration testing methodology and has called into serious question my membership in Team Zombie. Tip of the hat to Sandro for turning me and Voxdolo on to this technique.

Here’s a quick and dirty implementation of integration testing with rspec and webrat on Vurl (source), using the techniques I picked up this week.

Configure your application

In config/environment.rb:

1
2
config.gem 'rspec-rails', :lib => false, :version => '1.2.7.1'
config.gem "webrat", :version => "0.5.3", :lib => false

In spec/spec_helper.rb:

1
2
3
4
5
6
7
8
9
10
11
require 'webrat'

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

Spec::Runner.configure do |config|
  ...
  config.include(Webrat::Matchers, :type => [:integration])
  ...
end

Create your spec

1
mkdir spec/integration

Here’s my spec/integration/create_vurl_spec.rb file:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
require File.expand_path(File.join(File.dirname(__FILE__), '..', 'spec_helper'))

describe "Create Vurls" do
  it "redirects to the vurl show page" do
    submit_vurl 'http://google.com'
    current_url.should == vurl_url(Vurl.last)
  end 
  it "shows a success message" do
    submit_vurl 'http://google.com'
    response.body.should include('Vurl was successfully created')
  end 
  it "creates a vurl" do
    submit_vurl 'http://veez.us'
    Vurl.last.url.should == 'http://veez.us'
  end 
end

def submit_vurl url 
  visit root_path
  fill_in "vurl_url", :with => url 
  click_button 'Vurlify!'
end

Run your spec

Since your spec file ends in _spec.rb, it will run with the rest of your spec files. Just give your app a

1
rake spec

A note about rspec matchers

When running these rspec tests, we don’t have access to the rspec matchers. So things like

1
flash[:error].should_not be_nil

won’t work because the be_nil matcher isn’t loaded. You can always fall back to Test::Unit:

1
assert_not_nil flash[:error]

Or, better yet, test that your content is within the body:

1
response.body.should include('There was a problem creating your vurl')

This method of integration testing feels much lighter to me; the tests take less time than cucumber equivalents and we’re not writing and maintaining a separate set of regexes to go with the app.

blog comments powered by Disqus