sajad torkamani

Feature tests

A feature test is the most high-level test and typically involves testing a feature of your app through a web browser via Capybara.

See this post for more details.

Example: test that users can register

# frozen_string_literal: true

require 'rails_helper'

RSpec.describe 'Registration', type: :feature do
  describe 'when invalid details are submitted' do
    it 'Register form shows errors' do
      visit new_user_registration_path

      click_button 'Register'

      expect(page).to have_content default_error_message
    end
  end

  describe 'when valid details are submitted' do
    it 'User is registered' do
      attributes = attributes_for(:user)
      visit new_user_registration_path

      fill_in 'Email', with: attributes[:email]
      fill_in 'Password', with: attributes[:password], match: :prefer_exact
      fill_in 'Password confirmation', with: attributes[:password]
      click_button 'Register'

      expect(page).to have_content I18n.t('devise.registrations.signed_up')
      expect(page).not_to have_content default_error_message
    end
  end
end

Model tests

Model tests test Active Record models. Common things to test for include:

  • Correct validation rules are enforced.
  • Associations are setup properly.
  • Custom methods of model work as intended.

Example: test validations, association, and custom method

# frozen_string_literal: true

require 'rails_helper'

RSpec.describe User, type: :model do
  describe 'validations' do
    it { is_expected.to validate_presence_of(:email) }

    it 'is expected to validates that email is a valid email format' do
      user = build(:user, email: 'john@')

      expect(user).not_to be_valid
      expect(user.errors[:email]).to include 'is invalid'
    end

    it { is_expected.to validate_uniqueness_of(:email).case_insensitive }

    it { is_expected.to validate_presence_of(:password) }
    it { is_expected.to validate_length_of(:password).is_at_least(6) }
  end

  describe 'associations' do
    it { is_expected.to have_many(:quotes).dependent(:destroy) }
  end

  describe '#truncated_email' do
    it 'returns the first portion of email (before the @ symbol)' do
      user = build(:user, email: 'johndoe@example.com')
      expect(user.truncated_email).to eq 'johndoe'
    end

    it 'truncates the first portion of email if email is very long' do
      user = build(:user, email: 'abcdefghijklmnopqrstuvwxyz@gmail.com')
      expect(user.truncated_email).to eq 'abcdefghijklmnopq...'
    end
  end
end

Request specs

TODO