SpeedUp Rspec tests



Couple tips how to speed up you'r tests!

1. Shared examples (it_behaves_like)

class AgePolicy
def old_enough?(age)
age >= 18
end
end
require 'spec_helper'
describe AgePolicy do
describe '#old_enough?' do
it 'returns false if user is 16 years old' do
policy = AgePolicy.new
expect(policy.old_enough?(16)).to eq(false)
end
it 'returns false if user is 12 years old' do
policy = AgePolicy.new
expect(policy.old_enough?(12)).to eq(false)
end
it 'returns true if user is 18 years old' do
policy = AgePolicy.new
expect(policy.old_enough?(18)).to eq(true)
end
it 'returns true if user is 20 years old' do
policy = AgePolicy.new
expect(policy.old_enough?(20)).to eq(true)
end
end
end
Can be written:
require 'spec_helper'
describe AgePolicy do
describe '#old_enough?' do
shared_examples 'user eligible for taking an action' do |age|
it "returns true if user is #{age} years old" do
policy = AgePolicy.new
expect(policy.old_enough?(age)).to eq(true)
end
end
shared_examples 'user not eligible for taking an action' do |age|
it "returns false if user is #{age} years old" do
policy = AgePolicy.new
expect(policy.old_enough?(age)).to eq(false)
end
end
it_behaves_like 'user not eligible for taking an action', 16
it_behaves_like 'user not eligible for taking an action', 12
it_behaves_like 'user eligible for taking an action', 18
it_behaves_like 'user eligible for taking an action', 20
end
end


2. Custom matchers

class SomeController
def show
render json: { success: true }
end
end
describe SomeController do
describe 'GET #show' do
it 'returns success response' do
get :show, id: 11, format: :json
expect(JSON.parse(response.body)).to eq({success: true})
end
end
end
Should be
expect(response).to be_json_success
RSpec::Matchers.define :be_json_success do |expected|
match do |actual|
json_response = JSON.parse(actual.body)
expect(json_response['success']).to eq(true)
end
end

If you have a lot of equal custom matchers - move it to matchers.

3. Associations in factory
If you have a lot associations in model, avoid using it always.

FactoryGirl.define do
factory :user do
contact
location
end
end
FactoryGirl.define do
factory :user do
first_name { "John" }
last_name { "Doe" }
trait :with_location do
location
end
end
end

4. Transictions

let! method will create instance for each test.
Try use  let_it_be for creating only one. (like before :all)

require 'spec_helper'
describe User do
let(:user1) { FactoryGirl.create :user }
let_it_be(:user2) { FactoryGirl.create :user }
it 'does something' do
# test with user
end
it 'does something' do
# test with user
end
it 'does something' do
# test with user
end
end

http://pdabrowski.com

Comments