【rails】system spec

※本サイトで紹介している商品・サービス等の外部リンクには、アフィリエイト広告が含まれる場合があります。

画面が正しく表示されているか

ブラウザをプログラムで操作して、自分の期待通りに画面が表示されるかテストする

コントローラーは正しく動いていても、画面が正しく表示されていない可能性がある


テストの流れ

  1. 画面が正しく表示されているか確認したい
  2. 画面の表示に必要なデータを作成する
  3. プログラムでブラウザを操作
    →想定どおりに表示されているか確認する

system specを実行できる環境づくり

ブラウザを操作してプログラムを実行できるようにする

パソコンのブラウザを操作するため、ソフトウェアを入れる

brew install cask chromedriver

講義の動画ではbrew cask install chromedriverとされているが、現在はbrew install〜の形に変更されている

どうやって使うのか?

railsが用意してくれているので、すでに以下がインストールされている

  • capybaraは、rubyでブラウザを操作するためのメソッドを提供してくれる
  • selenium-webdriverwebdriversは、rubyからブラウザを操作しやすいようにしてくれている

specにsystemのフォルダを作る

通常は複数形だが、systemに複数形が存在しないのでこのままでok

次にarticle_spec.rbを作る

記事の一覧がしっかり画面表示されているのか確認する

※コントローラーでテストしたのは、「200が返ってくるかどうか」だけで、表示についてはテストできていない

まずは基本の形↓

require 'rails_helper'

RSpec.describe 'Article',type: :system do
  it '記事一覧が表示される' do
  end
end
  • describe(何についてテストするのか)→'Article'についてテストをする
  • typeを指定する
    →model spec、request spec、system spacでやることが全然違う
    →何のテストをするのかrailsに伝える必要がある

visitでブラウザを立ち上げる

Capybaraが用意してくれているメソッド

例えば、visit root_pathと書いてみる

RSpec.describe 'Article',type: :system do
  it '記事一覧が表示される' do
    visit root_path
  end
end

これを実行すると、ブラウザのトップの画面が一瞬開く

bundle exec rspec spec/system/article_spec.rb

ブラウザを立ち上げて画面のチェックができるので便利


ダミーデータを作り、記事が表示されているか確認する

これまでのテストと同じように、userarticleを作る

RSpec.describe 'Article',type: :system do
  let!(:user) { create(:user) }
  let!(:articles) { create_list(:article, 3, user: user) }

have_contentで、contentの有無を判断する

Capybaraが用意してくれているメソッド

    expect(page).to have_content(articles.first.title)

該当のページに「articles.first.title」という文字が存在しているかしていないのか判断する


テストを実行する

そしてまた実行してみる

bundle exec rspec spec/system/article_spec.rb

するとブラウザが立ち上がり、一瞬だけど記事が3つ表示されているのが見える

そしてテストは成功!(articles.first.titleは存在していた)


すべての記事についてテストする

先程は「first」だけだったので、3つともの記事についてテストする

  it '記事一覧が表示される' do
    visit root_path
    articles.each do |article|
      expect(page).to have_content(article.title)
    end
  end

テストを実行する

bundle exec rspec spec/system/article_spec.rb

テスト成功!


article.titleがページ内に存在するか確かめられた!

・・・でも、存在していても記事のタイトルじゃない可能性がある

article.titleと同じ文字だからといって、articleのtitleであるとは限らない)

そのため、have_contentだけでは不十分になることがある

#DAY15