Testing with rspec and capybara in rails

Wajeeh Ahsan
3 min readFeb 18, 2020

--

We’re supposing, you’ve a rails app already working. Now you want to write test cases for testing your rails app. Let’s see how to do.

Add gem 'rspec-rails' to your Gemfile in the :development, :test group.

group :development, :test do
...
gem 'rspec-rails', '~> 3.8', '>= 3.8.2'
end
  1. In the terminal window, run bundle install
  2. In the terminal window, run rails generate rspec:install .
  3. Add gem 'factory_bot_rails' to your Gemfile in the :development, :test group.
group :development, :test do
...
gem 'rspec-rails', '~> 3.8', '>= 3.8.2'
gem 'factory_bot_rails', '~> 5.1'
end

the terminal window, run bundle install

  1. Create a new directory at mkdir spec/factories/ by running mkdir spec/factories in the terminal window. This is required by factory_bot_rails
  2. Create a new directory at spec/support/ by running mkdir spec/support in the terminal window
  3. Create factory_bot.rb in spec/support by running touch spec/support/factory_bot.rb in the terminal window
  4. Open spec/support/factory_bot.rb and add the following:
RSpec.configure do |config|
config.include FactoryBot::Syntax::Methods
end

Add gem 'capybara' to your Gemfile in the :development, :test group.

group :development, :test do
...
gem 'rspec-rails', '~> 3.8', '>= 3.8.2'
gem 'factory_bot_rails', '~> 5.1'
gem 'capybara', '~> 3.29'
end
  1. In the terminal window, run bundle install
  2. Create capybara.rb in spec/support by running touch spec/support/capybara.rb in the terminal window
  3. Open spec/support/capybara.rb and add the following:
require 'capybara/rspec'
  1. Add gem 'database_cleaner' to your Gemfile in the :test group.
group :test do
gem 'database_cleaner', '~> 1.7'end
  1. In the terminal window, run bundle install
  2. Open spec/support/capybara.rb and add the following:
require 'capybara/rspec'RSpec.configure do |config|
config.use_transactional_fixtures = false
config.before(:suite) do
if config.use_transactional_fixtures?
raise(<<-MSG)
Delete line `config.use_transactional_fixtures = true`
from rails_helper.rb (or set it to false) to prevent
uncommitted transactions being used in JavaScript-
dependent specs.
During testing, the app-under-test that the browser driver
connects to uses a different database connection to the
database connection used by the spec. The app's database
connection would not be able to access uncommitted
transaction data setup over the spec's database
connection.
MSG
end
DatabaseCleaner.clean_with(:truncation)
end
config.before(:each) do
DatabaseCleaner.strategy = :transaction
end
config.before(:each, type: :feature) do
driver_shares_db_connection_with_specs = Capybara.current_driver
== :rack_test
unless driver_shares_db_connection_with_specs
DatabaseCleaner.strategy = :truncation
end
end
config.before(:each) do
DatabaseCleaner.start
end
config.append_after(:each) do
DatabaseCleaner.clean
end
end

Create Our First Test (Optional)

Now that our app’s test suite is configured with RSpec, Capybara, Factory Bot Rails and Database Cleaner, let’s write some tests to ensure everything is working.

In the terminal window, run rails db:migrate RAILS_ENV=test — traceto migrate the database. I’ve a user model already with following association in app/models/user.rb .

has_many :businesses, -> { distinct} , through: :memberships, dependent: :destroy

And business model with following validation in app/models/business.rb .

validates :name, :phone, :address1, :city, :state, :zip, :country,  presence: true

And a scope businesses to fined user’s approved business

scope :businesses, -> do  where(approved: true)end

Now generatespec/models/business_spec.rb by running following command:

rails generate rspec:model business

Update spec/models/business_spec.rb with the following code:

require 'rails_helper'RSpec.describe Business, type: :model do
context 'business scope test' do
before(:each) do
Business.new(name: 'Test1', phone: '12345678', address1: 'Test
Address-1', city: 'Test City-1', state: 'Test State-1', zip:
'1234', country: 'Test Country-1').save!
Business.new(name: 'Test2', phone: '12345678', address1: 'Test
Address-2', city: 'Test City-2', state: 'Test State-2', zip:
'1234', country: 'Test Country-2', approved:true).save!
Memberships.create(user_id: 2, business_id: Business.first.id) end it 'should return approved businesses for a user' do
expect(User.second.businesses.size).to eq(1)
end
end
end

Run rspec. It will first create two business, one with approved: true and one will have approved: false by default. Then it will create a membership of second user for first business in our database. Then it will retrieve all businesses of second user with approved: true which counts to 1.

--

--

Wajeeh Ahsan
Wajeeh Ahsan

No responses yet