Speed up your integration tests with a jig

February 7, 2014

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