Follow

Follow

Setup Rails testing stack with RSpec, Database Cleaner, FactoryBot, Shoulda Matchers and VCR

Anchieta Júnior's photo
Anchieta Júnior
·Aug 24, 2021·

3 min read

Setup Rails testing stack with RSpec, Database Cleaner, FactoryBot, Shoulda Matchers and VCR

Hello there, in this post, i'm going to setup RSpec and other tools inside a Ruby on Rails application and create a super consistent stack of tests.

Content of this post

I'm going to use the --api mode to generate a new Rails app since i don't want to create tests with Capybara or Cucumber in this case. I'm using Ruby 3.0.0 and Rails 6.1.4.1.

Creating a new project

rails new myapp -T --api

Adding new dependencies

Add these gems to their specific group:

# Gemfile

group :development, :test do
  gem 'rspec-rails', '~> 5.0.0'
end

group :test do
  gem 'database_cleaner-active_record', '~> 2.0.1'
  gem 'factory_bot', '~> 6.2.0'
  gem 'shoulda-matchers', '~> 5.0'
  gem 'faker', '~> 2.19.0'
  gem 'vcr', '~> 6.0.0'
end

Install everything using bundler:

bundle install

Setup RSpec

rails generate rspec:install

This command generates a new folder called spec* and new files with default RSpec configuration to the project, if everything was executed correctly we can run:

bundle exec rspec

In the recent created file rails_helper.rb uncomment this line to import support files we will create:

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

Screen Shot 2021-08-23 at 18.38.20.png

Setup DatabaseCleaner

DatabaseCleaner is a tool that helps us keep our test database clean. In this case we are using only DatabaseCleaner for ActiveRecord, however there are a lot of other options like Redis.

Create a new spec/support/database_cleaner.rb file:

RSpec.configure do |config|
  config.before(:suite) do
    DatabaseCleaner.strategy = :transaction
    DatabaseCleaner.clean_with(:truncation)
  end

  config.around(:each) do |example|
    DatabaseCleaner.cleaning do
      example.run
    end
  end
end

Setup FactoryBot

To setup FactoryBot, just require it in the rails_helper.rb file after require 'rspec/rails':

require 'rspec/rails'
require 'support/factory_bot'

Setup transactional_fixtures to false:

RSpec.configure do |config|
# ...
config.use_transactional_fixtures = false
# ...
end

Create a new support/factory_bot.rb file:

RSpec.configure do |config|
  config.include FactoryBot::Syntax::Methods
end

Setup Shoulda Matchers

Shoulda Matchers provides RSpec- and Minitest-compatible one-liners to test common Rails functionality that, if written by hand, would be much longer, more complex, and error-prone.

Create a new spec/support/shoulda_matchers.rb file:

Shoulda::Matchers.configure do |config|
  config.integrate do |with|
    with.test_framework :rspec
    with.library :rails
  end
end

Setup VCR

Record your test suite's HTTP interactions and replay them during future test runs for fast, deterministic, accurate tests.

You can update your spec_helper.rb like this:

require 'vcr'

VCR.configure do |c|
  c.ignore_localhost = true
  c.ignore_hosts 'api.segment.io'
  c.cassette_library_dir = 'spec/cassettes'
  c.hook_into :webmock
  c.configure_rspec_metadata!
end

Conclusion

Now we can create our specs, including specs that depend on third api calls, VCR will take care about it creating cassetes to record requests.

 
Share this