Integration testing without cucumber
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.