A couple months ago, Ben Lindsey wrote ‘Crank Your Specs’ which talked about how to speed up your test suite. I’ve been chatting with him since then, and trying to figure out other ways to shave some time off our ever growing suite of tests. Here’s a little trick I discovered that improved testing time.
We use RSpec to test both controllers and views. View testing in the controller tests is pretty easy. Simply add
in a describe block, and the response object from requests will contain a full html response.body (instead of mocking out the view creation) and send that back so you can add tests like
describe ArticlesController do integrate_views describe "#show" before do get :show, :id => articles(:nytimes).object_id end it "has a header" do response.should have_tag('h1') end end end
But there are plenty of controller tests that don’t need to see the view at all.
describe ArticlesController do describe '#index' do it "fetches all the articles" do assigns(:articles).should == Article.all end end end
Generating those views takes a bunch of time. And because the integrate_views keyword applies to individual describe blocks, you can specify it only where you need it, instead of at the beginning of the first describe block.
For a couple different projects, I ran through the current set of specs and removed integrate_views entirely. Then, after starting autospec, ran back through each spec file and inserted integrate_views into the nested describe blocks that needed them until i had all the controller specs passing again.
The refactored faster specs look like this:
describe ArticlesController do describe '#index' do it "fetches all the articles" do assigns(:articles).should == Article.all end end describe '#show' do integrate_views # only integrate views for this block before do get :show, :id => articles(:nytimes).object_id end it "has a title" do response.should have_tag('h1') end end end
Making this mod to 2 of the projects I’ve been working on resulted in the following gains:
Project 1: (Rails/ERB): ~800 specs. 171sec -> 134sec (27% speedup)
Project 2: (Rails/Erector): ~2000 specs. 13min -> 12min (8% speedup)