Rails Test Setup

written in rails, rspec

Here’s how I usually setup my test environment on Rails. I’m using mainly RSpec and Capybara, so nothing new under the sun, but this should provide a mindless copy and paste to get you (mainly me) started.

First of all, the gems used. This configuration is in part taken from the book “Testing with RSpec” by Aaron Summer:

Gemfile
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
group :development, :test do
  gem 'rspec-rails'
  gem 'factory_girl_rails'
  gem 'rb-fsevent', require: false if RUBY_PLATFORM =~ /darwin/i # only on OSX
  gem 'guard-rspec'
end

group :test do
  gem 'shoulda-matchers'
  gem 'faker'
  gem 'capybara'
  gem 'poltergeist'
  gem 'database_cleaner'  # DatabaseCleaner required to test user authentication protected routes
  gem 'launchy' # Provides the awesome save_and_open_page method in your capybara specs
end

A pretty basic setup, RSpec with shoulda matchers, FactoryGirl + Faker for cool mocks and Capybara with Poltergeist as webdriver.

You might want to install PhantomJS (used by Poltergeist). In Mac OSX you can just use brew:

1
brew install phantomjs

With that out of the way the next step is to setup RSpec

1
rails g rspec:install

I like to customize rspec with the dotted (or the documentation if I’m feeling verbose) and colored notation by adding a .rspec file.

.rspec
1
--color --format progress

Then I’ll customize the generators:

config/application.rb
1
2
3
4
5
6
7
8
9
10
config.generators do |g|
  g.test_framework :rspec,
    fixtures: true,
    view_specs: false,
    helper_specs: false,
    routing_specs: true,
    controller_specs: true,
    request_specs: false
  g.fixture_replacement :factory_girl, dir: 'spec/factories'
end

As you can see I let the generator create the fixtures (using FactoryGirl) and the controller and routes specs. I create models and request spec manually, and I don’t care for view specs.

That’s about it for Rails, the next step is to do some adjustments to the spec_helper:

spec/spec_helper_.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
ENV["RAILS_ENV"] ||= 'test'
require File.expand_path("../../config/environment", __FILE__)
require 'rspec/rails'
#require 'rspec/autorun' #removed to support Zeus
require 'capybara/poltergeist'

Dir[Rails.root.join("spec/support/**/*.rb")].each { |f| require f }

ActiveRecord::Migration.check_pending! if defined?(ActiveRecord::Migration)

RSpec.configure do |config|

  config.include FactoryGirl::Syntax::Methods
  config.filter_run_excluding slow: true
  config.fixture_path = "#{::Rails.root}/spec/fixtures"

  Capybara.javascript_driver = :poltergeist

  # DatabaseCleaner required to test user authentication protected routes
  config.use_transactional_fixtures = false

  config.before(:suite) do
    DatabaseCleaner.strategy = :truncation
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

  config.infer_base_class_for_anonymous_controllers = false
  config.order = "random"
end

This sets up DatabaseCleaner and the webdriver for Capybara. It also tells RSpec to skip tests marked as :slow.

Other goodies

Almost there, now it’s time to setup a couple of tools that makes testing less cumbersome. First of all, let’s setup Guard.

1
guard init rspec

… and that’s about it.

Let’s finish off by configuring Zeus if needed (or wanted). That’s pretty straightforward, we just need to change the test environment command in the zeus.json generated by zeus init:

zeus.json
1
2
3
"test_environment": {
  "test_helper": {"test": ["rspec"]}
}

And that should be it, therefore

1
expect(post).to be_helpful # I'm quite the commedian

Comments