Potential gotcha with test setup in Rails 2.0

Wednesday, December 05

UPDATE 2: This is now fixed in Rails trunk.

UPDATE 1: Josh Peek has already created a patch that prevents this gotcha. Read the patch and give it a +1 on the Rails Trac if you’re so inclined: http://dev.rubyonrails.org/ticket/10382.

Rails 2.0 introduces a new (better) way to create your functional test cases. Instead of subclassing Test::Unit::TestCase directly, you can now subclass ActionController::TestCase, which will take care of the setting up the request/response environment for you. Here’s what a Rails 2.0 functional test might look like:

require File.dirname(__FILE__) + '/../test_helper'

class AuctionsControllerTest < ActionController::TestCase
  def test_should_require_login_for_create
    assert_login_required 'create'
  end
  # ...
end

Now, suppose you’re using the setup method to prepare a few things before each of your test methods run. You may remember that prior to this change, each functional test needed to define its own setup method in which it created a controller instance, and instances of TestRequest and TestResponse. Well, it still does. Only this setup method is moved to the new superclass, saving you the typing.

And therein lies the gotcha: if you go ahead and create your own setup method not realizing that you’ve inherited one, you’ll clobber the one defined in the superclass. So, when you’re defining your own setup method, remember to call the original one using super:

require File.dirname(__FILE__) + '/../test_helper'

class AuctionsControllerTest < ActionController::TestCase
  def setup
    super
    @current_user = login_as(:amy)
  end

  def test_should_require_login_for_create
    assert_login_required 'create'
  end
  # ...
end

Hopefully this will save you the 15 minutes I spent trying to figure out why this wasn’t working.

Faster Fixtures in Rails 2.0

Monday, October 01

Rails 2.0 includes optimizations for the loading of fixtures in tests that offer a significant speedup. After updating one of my projects to the latest from svn, my tests are running up to 50% faster than before.

Units:
  • before: 17s
  • after: 12s
  • improvement: ~ 30%
Functionals:
  • before: 10s
  • after: 5s
  • improvement: ~ 50%

This particular project has a lot of tests, and to be honest, even 12 seconds is too slow for my tastes. But the improvement sure is welcome. In newer projects, I’m using UnitRecord to test without the database. Obviously, this is much faster. But for fixture-dependent projects, upgrading to Rails 2.0 will yield a significant improvement out of the box.