[Rails]テストコード の書き方


背景

テストコードを書くのがとても苦手で嫌いだったのですが、克服するために勉強しました。
その、自分が必死に勉強した内容をまとめて備忘録として記載します。
(一番下にテストコードの記載例あります)

手順

※まず単体テストから↓

1.Gemfileに以下を記述する。

group :development, :test do
  gem 'rspec-rails', '~> 3.8'
  gem 'factory_bot_rails', '~> 5.0'
end

忘れず実行する。

$ bundle install

2.正しくインストールされているか確認する。


$ bundle exec rspec --version
# rspecの確認
$ bundle exec gem list | grep factory_bot_rails
# FactoryBotの確認

3.RSpecを利用できるようにする。

$ rails generate rspec:install

4.テスト用DBを最新の構成にする

$ rails db:migrate:reset RAILS_ENV=test

5.モデルのテストコードを作成する


$ rails generate rspec:model モデル名
# models配下にモデルのテストコードを書くためのファイル(雛型)が生成される

6.spec/factoriesのなかの対応するモデルにテストデータを準備する。

user.rb
FactoryBot.define do

  factory :モデル名 do
    カラム名     {"仮の値"}
  end

end

7.spec/models/の中のファイルにテストコードを書く

user.rb

require 'rails_helper'

RSpec.describe モデル名 do
  describe '#メソッド名' do
    before do
        前提条件
    end
    context 'グループ分けの説明' do
      before do
        このグループの前提条件
      end
      it 'テストの説明' do
        テスト内容
      end
    end
  end
end

8.RSpecを実行する

$ bundle exec rails test test/models/user.rb

9.各モデルの共通メソッドのテストコードのファイルを作成する

$ mkdir -p spec/support/concerns/

$ touch spec/support/concerns/common_module.rb

10.spec/support/concerns/common_module.rbに共通メソッドのテストコードを書く

common_module.rb

shared_examples 'テストの説明' do
 ~ 
end

11.呼び出し元のモデルに下記記述を追記する。

user.rb
describe '共通メソッド' do
    it_behaves_like 'テストの説明'
end

12.RSpecを実行する

$ bundle exec rails test test/models/user.rb

13.共通のバリデーションも共通メソッド同様の手順で定義する。

14.コントローラーのテストコードを作成する

$ rails generate rspec:integration モデル名

15.テストコードを書く

users.rb
require 'rails_helper'

RSpec.describe "users/index", type: :view do
  describe 'index.html.erbのテスト' do
    it 'h1タグ内にUsersが表示されているかどうか' do
      visit users_path
      expect(page).to have_selector('h1', text: 'Users')
    end
  end
end

16.RSpecを実行する

$ bundle exec rails test test/requests/users.rb

※ここから結合テスト↓

17.Gemfileに以下を追記する。

group :test do
  gem 'capybara', '~> 3.28'
  gem 'selenium-webdriver', '~> 3.142'
  gem 'webdrivers', '~> 4.1'
end

忘れず実行する。

bundle install

18.インストールされている確認する

bundle exec gem list | grep -e capybara -e selenium-webdriver  -e webdrivers

19.spec_helper.rbに以下を追記する。

spec_helper.rb

require 'capybara/rspec'

RSpec.configure do |config|
  config.before(:each, type: :system) do
    driven_by :selenium, using: :chrome, screen_size: [1280, 960]
  end

20.結合テストのテストコードのファイルを作成する

$ mkdir -p spec/system/

$ touch spec/system/対応するモデル名_spec.rb

21.テストコードを書く

22.RSpecを実行する

テストコード記載例

spec/factories/モデル名.rb


FactoryBot.define do

  factory :モデル名 do
    name     {"tanaka"}
    age      {23}
    ...
  end

end

spec/models/モデル名.rb

user.rb
require 'rails_helper'

RSpec.describe モデル名 do
  describe '#メソッド名' do
    before do
        前提条件
    end
    context 'グループ分けの説明' do
      before do
        このグループの前提条件
      end
      it 'テストの説明' do
        テスト内容
      end
    end
  end
end

spec/requests/コントローラー名.rb

users.rb

require 'rails_helper'

RSpec.describe "頭文字が大文字のコントローラー名", type: :request do
  describe "HTTPリクエスト /URL" do
    it "テストの説明(HTTPレスポンスが200になる)" do
      get users_path
      # getリクエストでパス指定
      expect(response).to have_http_status(200)
      # responseに対してhave_http_statusというマッチャで200と等しいかを確認
    end
  end
end

spec/upport/concerns/common_module.rb

common_module.rb
shared_examples '説明' do
  let ~
  context '説明' do
    it '説明' do
      expect(model).not_to be_valid
      expect(model.errors[:name]).to include(I18n.t('errors.messages.blank'))
    end
  end
end

system/モデルの複数形.rb

users.rb
require 'rails_helper'

RSpec.describe モデル名 do
  describe '正常系' do
    before do
        前提条件
    end
    context 'グループ分けの説明' do
      before do
        このグループの前提条件
      end
      it 'テストの説明' do
        テスト内容
      end
    end
  end

 describe '異常系' do
    before do
        前提条件
    end
    context 'グループ分けの説明' do
      before do
        このグループの前提条件
      end
      it 'テストの説明' do
        テスト内容
      end
    end
  end
end