stderr

secondary output stream of a software developer

Organizing Integration Test Helpers with Dominos

The domino gem by Nick Gauthier provides a great way to organize your integration test support methods. Before, I used to package test helpers as mixins.

# spec/features/admin/user_locking_spec.rb
feature 'user locking' do
  include UsersTestHelper

  scenario 'locking a user account' do
    user = create(:user)

    visit user_path(user)
    lock_user_button.click

    expect(page).to have_locked_notice
  end
end

# spec/support/integration/users_test_helper.rb
module UsersTestHelper
  extend RSpec::Matchers::DSL

  def lock_user_button
    page.find('section.user [data-rel=lock]')
  end

  matcher :have_locked_notice do |*args|
    # check if there is an element matching .lock_notice
  end
end

While those usally made for quite readable tests, there were two major downsides:

  • Findability — It quickly became hard to tell where a certain helper method was defined as soon as more than one or two mixins were used in a test.

  • Naming clashes — Extracting private methods to clean up test helper methods came with the risk of introducing name collisions.

With dominos you can take a more object oriented approach:

# spec/support/dominos/user_page.rb
module Dom 
  UserSection < Domino
    selector 'section.user'

    def lock_button
      node.find('[data-rel=lock]')
    end

    def has_locked_notice?
      node.has_selector?('.lock_notice')
    end
  end
end

The test from above now becomes:

# spec/features/admin/user_locking_spec.rb
feature 'user locking' do
  scenario 'locking a user account' do
    user = create(:user)

    visit user_path(user)
    Dom::UserSection.first.lock_button.click

    expect(Dom::UserSection.first).to have_locked_notice
  end
end

While this arguably reads a bit more cryptic at first, there are a couple of wins:

  • It is now directly obvious where each methods is defined.
  • Private methods can freely be extracted inside dominos.
  • Custom matchers can be replaced by RSpec's built in predicate matchers.
  • It is easy to adapt a component based mental model of your UI.

While there are other great features, the domino codebase only clocks in at about 160 LOC including doc comments. So its a rather lightweight dependency to add to your testing stack.

comments powered by Disqus