Debugging Rails Integration Tests

Rails integration tests can be difficult to debug. The tests are usually coarse grained, which makes isolating the cause of failure difficult. A test to simply make sure a page is working (smoke test) might look like this:

def test_get_show_user_url
  get show_user_url(User.find(:first))
  assert_response :success
end

This test is sufficient to make sure M, V, and C are all playing nice together. However, if an exception is raised, the output from the test is this:

Expected response to be a <:success>, but was <500>

Clearly not helpful in knowing what went wrong.

The easiest thing to do is display the rendered output from the 500:

def test_get_show_user_url
  get show_user_url(User.find(:first))
  assert_response :success, @response.body
end

Here, @response.body is the message for the assertion, and is only displayed if the response is not success. This provides output that helps debug test failures, but the output is really noisy. It's the HTML page that you normally see in your browser with a 500, and contains several stack traces and other debugging info. It's great in the browser, not so great in the console.

The best way to make the failures easy to debug is to let the exception be rescued by the test instead of by the controller. To do this, you need to tell the controller and the dispatcher not to rescue:

ActionController::Base.class_eval do
  def perform_action
    perform_action_without_rescue
  end
end

Dispatcher.class_eval do
  def self.failsafe_response(output, status, exception = nil)
    raise exception
  end
end

This code should go in the test helper for your test suite. Conventionally this will be: test/integration/integration_test_helper.rb