2021年10月5日 現場Rails Chapter5-12 詳細表示機能のSpecを追加する
詳細表示機能Specを追加する
前回の一覧表示機能に続いて、詳細表示機能のテストコードを追記します。
describe 'タスク管理機能', type: :system do let!(:task_a) { FactoryBot.create(:task, name: '最初のタスク'), user: user_a)} ...省略 describe '詳細表示機能' do context 'ユーザーAがログインしているとき' do let(:login_user) { user_a } before do visit task_path(task_a) end it 'ユーザーAが作成したタスクが表示される' do expect(page).to have_content '最初のタスク' end end end end
let!を用いてtask_aを定義しておくと、タスク作成処理を共通化することが出来るため、一覧表示機能でタスクを作成する処理を記述する必要がなくなります。
shared_examplesを利用する
共通したitの内容をまとめる事ができる機能です。
今回の例の場合、詳細表示機能のテストと一覧表示機能のテストで
itの内容が被ってしまっています。
その場合に、以下のようにshared_examplesを用います。
shared_examples_for 'ユーザーAが作成したタスクが表示される' do it { expect(page).to have_content '最初のタスク' } end
このように共通化の記述をした上で、これまでitを書いていた場所には以下のように書きます。
it_behaves_like 'ユーザーAが作成したタスクが表示される'
使用上の注意としては、すぐに理解できる名前にし、可読性を損なわないようにする必要があります。
新規作成機能のSystem Spec
describe 'タスク管理機能', type: :system do describe '新規作成機能' do let(:login_user) { user_a } before do visit new_task_path fill_in 'Name', with: task_name click_button '登録する' end context '新規作成画面で名称を入力したとき' do let(:task_name) { '新規作成のテストを書く' } it '正常に登録される' do # .alert-successというCSSクラスを指定している # 特定のタグやCSS要素に特定の文字列が表示されていることを検証する expect(page).to have_selector '.alert-success', text: '新規作成のテストを書く' end end context '新規作成画面で名称を入力しなかったとき' do let(:task_name) { '' } it 'エラーとなる' do # 検証エラーを表示する領域内に、「名称を入力してください」というエラーメッセージが表示される。 within '#error_explanation' do expect(page).to have_content '名称を入力してください' end end end end end
withinメソッド
画面内の特定の範囲に絞って検証することが出来ます。 '名称を入力してください'というエラーメッセージが画面内に1つだけしか存在しない場合などを想定した上でerror_explanationというidの要素を指定して検証しています。
letの上書き
同じ名前のletを複数回定義すると、常に下の階層に定義したletが使われます。つまり、letは上書きができます。しかし、同じ名前のletを複数回定義すると、最終的にどのletが使われるのか分からなくなります。そのため、適切なバランスでletを使います。
describe 'タスク管理機能', type: :system do describe '新規作成機能' do let(:login) { user_a } let(:task_name) { '新規作成のテストを書く' } # デフォルトとして設定 before do ... end context '新規作成画面で名称を入力したとき' do it '正常に登録される' do expect(page).to have_selector '.alert-success', text: '新規作成のテストを書く' end end context '新規作成画面で名称を入力しなかったとき' do let(:task_name) { '' } # 上書き it 'エラーになる' do within '#error_explanation' do expect(page).to have_content '名称を入力してください' end end end end end