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
- Creating a new Project
- Adding new dependencies
- Setup RSpec
- Setup DatabaseCleaner
- Setup FactoryBot
- Setup Shoulda Matchers
- Setup VCR
- Conclusion
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 }
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.