今回のテストを行うアプリの流れ
ログイン
⬇️
目標を決める
⬇️
正常に目標が保存されたら、トップページへ遷移する
RSpecでnewアクション機能の一連の流れをテスト(総合テスト)するにあたり、
ログイン状態にさせてから目的の実装を行うための方法をまとめました。
私自身が初学者のため、同じような方向けの内容となっています。
環境
Ruby 2.6.5
Rails 6.1.3.1
以下インストール済み
Devise 4.8.0
RSpec 3.10.0
FactoryBot
Faker
前提
devise導入後、authenticate_userを使って、
applicationコントローラーのlpアクション以外に__非ログイン状態__でアクセスすると、
ログイン画面にリダレクトされるようにしています。
class ApplicationController < ActionController::Base
#ログインしていない場合はログイン画面へ強制的に遷移する
before_action :authenticate_user!, except: [:lp]
before_action :configure_permitted_parameters, if: :devise_controller?
~中略~
end
テストコード書き方
RSpecでDeviseを使えるようにする
RSpec.configure do |config|
~中略~
#下のコードを追記
config.include Devise::Test::IntegrationHelpers, type: :system
end
こちらをrails_helper.rbに記述することで、systemテスト時にdeviseのヘルパーを呼び出すことができます。
※system以外のrequestなどでも同様に使用できます。
テスト用データを用意
FactoryBotを使ってユーザーのテスト用データを用意します。
今回はユーザーデータと目標データの2つが必要なので2つのデータを作りました。
FactoryBot.define do
factory :user do
nickname { 'Taro' }
email { Faker::Internet.free_email }
password { 'aaBB1234' }
password_confirmation { password }
family_name { '田中' }
given_name { '太郎' }
birth_day { '1999-01-01' }
end
end
FactoryBot.define do
factory :goal do
saving_goal { '500000' }
purpose { '海外旅行を行くため' }
period { '2040-01-02' }
association :user
end
end
ユーザーモデルにfamily_nameカラムなどを追加している場合は追加したカラムのデータも記述します。
emailカラムはFakerを使ってダミーデータを生成してみました。
総合テスト用ファイルを作る
require 'rails_helper'
RSpec.describe 'ゴール新規登録', type: :system do
before do
#テスト用データを読み込む
@goal = FactoryBot.build(:goal)
@user = FactoryBot.create(:user)
end
context '新規登録できること' do
it '正しい情報を入力すればゴール新規登録ができてトップページに移動する' do
# 【sign_in @user】 によって、ログイン状態にする
sign_in @user
visit new_goal_path
fill_in 'goal_saving_goal', with: @goal.saving_goal
select '2022', from: 'goal_period_1i'
select '12', from: 'goal_period_2i'
select '12', from: 'goal_period_3i'
fill_in 'goal_purpose', with: @goal.purpose
expect do
find('input[name="commit"]').click
end.to change { Goal.count }.by(1)
expect(current_path).to eq(root_path)
end
end
先ほどrails_helperにDeviseをincludeしたので__sign_in__というヘルパーが利用できます!
sign_inによってログイン状態を作ることができるので、ログインしている場合の総合テストが簡単に実装できるはずです。
最後に
ご覧いただき、ありがとうございます。
私はこの方法で実装できましたが、うまくいかないこともあるかと思います。
sign_inヘルパーを使用しなくとも、before do~end内で行う実装方法も見つけたため、
こちらも残しておきます。参考になれば、嬉しいです。