RSpec編3

2021.4.21

ログイン処理を共通化する

supportディレクトリ作成

% mkdir support

supportディレクトリ下にファイル作成・編集

% touch login_macoros.rb

(spec/support/login_macros.rb)

module LoginMacros
def login_as(user)
visit root_path
click_link 'Login'
fill_in 'Email', with: user.email
fill_in 'Password', with: 'password'
click_button 'Login'
end
end

rails_helper.rbを編集

supportディレクトリを読み込む
Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }
#(support/login_macros.rb)で作成したモジュールを使用できるようにする
RSpec.configure do |config|
config.include LoginMacros #追記

 

メソッドを使用する

RSpec.describe 'UserSessions', type: :system do
let(:user) { create(:user) }
省略
context 'ログアウトボタンをクリック' do
it 'ログアウト処理が成功する' do
login_as(user)
click_link 'Logout'
expect(page).to have_content 'Logged out'
expect(current_path).to eq root_path
end
end
end

 

let let! 違い

let 定義した定数が初めて使われたときに評価される。遅延評価。

この場合、login_as(user)userが出てきたときに、usercreateされる。

RSpec.describe 'UserSessions', type: :system do
let(:user) { create(:user) }
 
describe 'ログイン後' do
context 'ログアウトボタンをクリック' do
it 'ログアウト処理が成功する' do
login_as(user)
click_link 'Logout'
expect(page).to have_content 'Logged out'
expect(current_path).to eq root_path
end
end
end
end

 

 

let! 各テストのブロックの実行前に定義した定数を作成する。事前評価。

↓がletだと、事前に定数が定義されていないのでエラーになる。

describe 'タスクの削除' do
let!(:task) { create(:task, user: user) }

it 'タスクの削除が成功する' do
visit tasks_path
click_link 'Destroy'
expect(page.accept_confirm).to eq 'Are you sure?'
expect(page).to have_content 'Task was successfully destroyed.'
expect(current_path).to eq tasks_path
expect(page).not_to have_content task.title
end
end

 

まとめ

let →定義した定数が初めて出てきたときにcreateされる
let!→各ブロック実行前に定数をcreateする

参照

rspec 「let」と「let!」の違い - Qiita

 

create_listについて

RSpecテストを書いているときに、複数のインスタンスをまとめて作成することができる。第1引数元になるファクトリ第2引数作成する数を指定する。

context 'タスクの一覧ページにアクセス' do
it '全てのユーザーのタスク情報が表示される' do
task_list = create_list(:task, 3)
visit tasks_path
expect(page).to have_content task_list[0].title
expect(page).to have_content task_list[1].title
expect(page).to have_content task_list[2].title
expect(current_path).to eq tasks_path
end
end

参照

RSpecでFactoryBotから複数のインスタンスをまとめて作成する【create_listを使用】 - Qiita

 

RSpec実行時のテストケースを:focus指定で限定できるように設定する

特定のexample(it)のみ実行していときに使用する。

使い方

(rails_helper.rb)

focus: trueを使用できるようにする。

RSpec.configure do |config|
config.filter_run_when_matching :focus #追記
end

(もともと)

it 'マイページへのアクセスが失敗する' do
visit user_path(user)
expect(page).to have_content ('Login required')
expect(current_path).to eq login_path
end

① itをfocusに変更

focus 'マイページへのアクセスが失敗する' do
visit user_path(user)
expect(page).to have_content ('Login required')
expect(current_path).to eq login_path
end

②さらに短縮。focusの頭文字のfをとったfitという別名を使用する。

特定のテストを実行したいときにfをタイプし、終わったら消す。

仕様テストのグループ(describe, context)についても、同様のショートカットが可能。fdescribe fcontext の形。

fit 'マイページへのアクセスが失敗する' do
visit user_path(user)
expect(page).to have_content ('Login required')
expect(current_path).to eq login_path
end

 

参照

RSpecで特定のテストを実行する方法