RSpecでよく使ったマッチャまとめ
2ヶ月に渡り既存アプリの修正課題をやっていく上で、たくさんのテストを書きました。RSpecは今後の実装でも間違いなく使っていくことになるので、その際に辞書的に使えるように復習も兼ねて簡単にマッチャをまとめました。
※あくまでも自分用の備忘録なので雑です...
visit、fill_in、click_on、have_content
describe '記事作成画面で画像ブロックを追加' do context '画像を選択せずにプレビューを閲覧' do it 'プレビューが正常に表示される' do visit new_admin_article_path fill_in 'タイトル', with: 'title' fill_in 'スラッグ', with: 'slag' fill_in '概要', with: 'body' click_on '登録する' click_on 'ブロックを追加する' click_on '画像' click_on 'プレビュー' expect(page).to have_content 'Blog' expect(page).to have_content 'title' end end end
reload, eq
describe '編集画面で更新を押した際ステータスが自動的に変化する' do context 'ステータスが下書き以外' do it '公開日時が未来だと、ステータスが公開待ちに更新される' do visit edit_admin_article_path(article.uuid) fill_in '公開日', with: '2020-12-24 10:00' click_on '更新する' expect(page).to have_content '更新しました' expect(page).to have_content '公開待ち' article.reload #ステータスが変化するものは、reloadを挟まないと正しく判定されない expect(article.state).to eq 'publish_wait' # have_contentはhtmlにその記述があるかどうか、eqはオブジェクトの 中身の属性が等しいかを判定する end end end
within, click_link
describe 'タグ一覧画面' do it 'タグ のパンくずをクリックした時にタグ一覧画面に遷移すること' do visit edit_admin_tag_path(tag) within('.breadcrumb') do click_link 'タグ' # withinでは、指定したセレクタの中身だけが判定される。今回だとclass: 'breadcrumb'内。click_linkはクリックするものがリンクの場合 end expect(current_path).to eq(admin_tags_path) # このように、urlとurlが等しいかどうかも判定することが可能 end end
switch_to_window(windows.last), have_css, have_selector
describe 'アイキャッチの横幅を変更' do context '横幅を100-700pxに指定した場合' do it 'プレビューで画像が正常に表示される' do eyecatch_width = rand(100..700) fill_in 'article[eyecatch_width]', with: eyecatch_width click_button '更新する' expect(page).to have_content('更新しました') click_link('プレビュー') switch_to_window(windows.last) # リンクが別タブで開かれてしまう場合などに、別タブに移動してそのタブの要素をテストすることができる expect(page).to have_css('.eye_catch') # 指定されたcssが存在するかどうか判定できる expect(current_path).to eq(admin_article_preview_path(article.uuid)) expect(page).to have_selector("img[src$='eye_catch.jpg']") # こちらは指定されたselectorが存在するかどうかの確認ができる。検証ツールを使うと各セレクターの名前がわかりやすい。 end end end
have_http_status
describe 'ライターの権限でログインした際に制限をかける' do context 'タグ編集画面のテスト' do let(:tag){ create :tag } it 'タグ編集画面にアクセスすると403エラーが表示される' do visit edit_admin_tag_path(tag) expect(page).to have_http_status(403) # そのページのhttpステータスをテストすることができる。 end end end
select ’○○’ from ‘○○’
describe '埋め込みタイプ' do before do login_as(admin) article visit edit_admin_article_path(article.uuid) click_on 'ブロックを追加する' click_on '埋め込み' click_on '編集' end context 'twitterを選択し、URLを入力' do it 'ツイートが正常に表示される' do select 'Twitter', from: 'embed[embed_type]' # 'embed[embed_type]'に登録されているものの中から 'Twitter'をセレクトする fill_in 'ID', with: 'https://twitter.com/2FnWaNQxNZRGcv0/status/1360535101948370945' page.all('.box-footer')[0].click_button('更新する') #これは、class: 'box-footer'とついている要素を全て取り出して配列にし、その中の一番最初の要素([0])を選択している。 click_on 'プレビュー' switch_to_window(windows.last) expect(current_path).to eq(admin_article_preview_path(article.uuid)) expect(page).to have_selector("iframe[title='Twitter Tweet']") end end end
be_truthy, match
expect(mail.present?).to be_truthy, 'メールが送信されていません' # be_truthyは、引数の中身がtrueかどうかを判定する。反対はbe_falsey describe '公開済記事の集計結果メールの送信' do context '昨日公開された記事がない' do fit '昨日公開された記事はありませんと本文に表示される' do check_sent_mail expect(mail.body).to match '昨日公開された記事はありません' # matchは今回の例だとhave_contentと同じ効果。have_contentでも通る。ただmatchだと配列やハッシュも判定できるらしい。 end end end