Cucumber testing with OmniAuth

Yesterday I needed to write some cucumber tests to cover the login and new user creation aspects of a RoR site I am working on. The site handles authentication via OAuth using the incredibly handy OmniAuth Gem, which I highly recommend. At first I thought I would have to decide to either bypass, and therefore not really test, much of the OAuth functionality, or I would need to spend a log of time mocking out the interaction with the external OAuth providers. However, I quickly learned from this blog post that Omniauth added some really awesome testing functionality which does this for you.

I wanted to test that existing users could login using the various OAuth providers. My cucumber test case ended up looking like the following:

Scenario Outline: User Login
  Given A user with name "Inigo Montoya" and UID "42" and auth provider "<provider>"
  When I visit the home page
  And I login using "<provider>" as the user
  Then I should see "My Profile" in the header
  And I should see "Sign Out" in the header
  And I should be on the "home" page

    |google |
    |twitter |

In the first step I need to create a user that included an auth provider, which proved slightly trickier than I expected. My Application supports multiple auth providers and my user and auth_provider models look like the following:

class User < ActiveRecord::Base

  has_many :auth_providers

  def self.create_with_omniauth(auth)
    create! do |user|
      user.auth_providers << => auth['provider'], :uid => auth['uid'])
      name = auth['info']['name'] = name

class AuthProvider < ActiveRecord::Base
  belongs_to :user

I am using FactoryGirl and my factory definitions look like this:

factory :user do
  ignore do
    uid '1234'
    provider 'google_oauth2'

  after(:create) do |user, evaluator|
    FactoryGirl.create :auth_provider, :user => user, :uid => evaluator.uid, :name => evaluator.provider

factory :auth_provider do

Which allows me to write a user creation step like this:

Given /^A user with name "(.*?)" and UID "(.*?)" and auth provider "(.*?)"$/ do |username, uid, provider|
  provider = 'google_oauth2' if provider.eql?('google')
  @user = FactoryGirl.create :user, :name => username, :uid => uid, :provider => provider

Then, after visiting my home page, I have my login step which looks like this.

When /^I login using "(.*?)" as the user$/ do |provider|
  logon(provider,, @user.auth_providers.first.uid)

def logon(provider, username='Inigo Montoya', oauth_uid='123')
  provider = 'google_oauth2' if provider.eql?('google')
  OmniAuth.config.add_mock(provider.to_sym, {:uid => oauth_uid, :provider => provider, :info => {:name => username}})

  visit '/'
  click_link 'Sign In'

  case provider
    when 'google', 'google_oauth2'
      click_link 'Google_128'
    when 'twitter'
      click_link 'Twitter_128'
    when 'facebook'
      click_link 'Facebook_128'
      fail("Unknown auth provider: '#{provider}'")

If there is any magic, it’s in the line with the call to Omniauth.config.add_mock which basically sets up a callback with the supplied data. However for that to work, you have to put OmniAuth in test mode, which is where the @omniauth_test tag in the original cucumber scenario comes in. I have that tag defined features/support/omniauth.rb which looks like this:

Before('@omniauth_test') do
  OmniAuth.config.test_mode = true

After('@omniauth_test') do
  OmniAuth.config.test_mode = false

I definitely have mixed feelings about using tags like this since it definitely would seem to be an example of technical details bleeding into scenarios which are supposed to be at a higher level of abstraction. However, it is a very convenient way to handle the overhead, so at least for now, I’ll handle it in this way.

3 responses to “Cucumber testing with OmniAuth”

  1. Awesome Post! (Actually this is just the author testing comments)

  2. Thanks for this post. This is exactly what I was looking for.

Leave a Reply

Your email address will not be published. Required fields are marked *