Speed Up Your Integration Tests with a Jig

February 7, 2014

[agile] [ruby] [testing]

If you've written enough integration tests (with Capybara et al.), you must have noticed how much time your tests spend just logging into your web app. Even if it takes 1 second each time, it starts to add up. Here's a solution that I've written several times, now. I create a test "jig" that allows me to authenticate into my application with a single visit.

class AuthenticationJigController < Devise::SessionsController
  def create
    resource = User.find_by_email!(params[:email])
    set_flash_message(:notice, :signed_in) if is_flashing_format?
    sign_in(resource_name, resource)
    yield resource if block_given?
    redirect_to root_url
  end
end

This is a simple override of the normal Devise session controller. Next I add a route that is only present in a development or testing environment.

# config/routes.rb
devise_scope :user do
  # DO NOT REMOVE THE if .. end FROM THIS ROUTE
  # IT WILL OPEN A HUGE, GAPING MAW OF A SECURITY HOLE
  # ...
  # FOR REALZ, NOT EVEN KIDDKING. OKAY?
  if Rails.env.development? || Rails.env.test?
    get "/users/auth" => "authentication_jig#create"
  end

There, that's about it. Now, whenever you need to authenticate to your system, say in a Capybara test, you can replace your multi-line login steps with a single visit "/users/auth?email=user@example.com".

And you will be authenticated!

I also use this during development to log in as different test users by creating bookmarks in my browser.

Speed Up Your Integration Tests with a Jig - February 7, 2014 - Ken Mayer