学習記録

アウトプット用に作りました

System Spec

システムスペックとは

複数のモデル、コントローラを統合したプログラム全体の挙動をチェックする統合テストです。またJavaScriptを利用する画面のテストを書くこともできます。

システムスペックには下記の機能がデフォルトで準備されています。

selnium-webdriverとはブラウザを自動で操作してテストする機能です。

トランザクション管理とは一連のSQL文をセットで扱い、全て正常に完了したら全テーブルの変更を「確定」し、万が一途中でエラーが発生したら全テーブルの変更を「破棄」するという意味です。


システムスペックの準備

gemの追加

capybaraとwebdriversというgemをbundle installします。
railsのテスト環境でのみ使えるようにします。

group :test do
  gem 'capybara'
  gem 'webdrivers'
end

capybaraを使うことでリンクをクリックしたり、webフォームを入力したり、画面の表示を検証することができるようになります。
webdriversはselnium-webdriverとchromedriver-helperの代替です。Chromeを使用してテストを動かすことができます。

capybaraの初期設定

capybaraの設定ファイルを作成します。

$ mkdir spec/support
$ touch spec/support/capybara.rb

作成したファイルにテストの設定を記入します。

spec/support/capybara.rb

RSpec.configure do |config|
  config.before(:each, type: :system) do
    driven_by :selenium, using: :headless_chrome
  end
end

using: :headless_chromeを指定することで、テスト毎に開かれるブラウザを非表示にすることができます。

上記のファイルをspec/spec_helper.rbに読み込みます。

require 'support/capybara'


ログイン処理をmoduleを作成して共通化

spec/supportディレクトリ配下にlogin_module.rbファイルを作成します。

$ touch spec/support/login_module.rb

作成したファイルの中身を記入していきます。

module LoginModule
  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にて作成したファイルを読み込みます。

RSpec.configure do |config|
  config.include LoginModule
end

rails_helper.rbの23行目あたりの一文をコメントアウトします。
これはspec/support配下のファイルを読み込むための設定です。

Dir[Rails.root.join('spec', 'support', '**', '*.rb')].sort.each { |f| require f }


実行するテストケースを限定

spec_helper.rbの50行目あたりの一文を有効にします。

config.filter_run_when_matching :focus

この設定をすることで実行したいテストブロックにfをつけることで、そのブロックのみ実行することができます。下記ではitにfをつけることで他にもたくさんあるテストの中からこの一つのテストケースだけテストすることができるようになります。

fit 'タスクの新規作成ページに遷移しない' do
  visit new_task_path
  expect(current_path).to eq login_path
  expect(page).to have_content "Login required"
end


システムスペックを実装

まず最初にgeneratorを使って実行ファイルを作成していきます。

$ rails generate rspec:system users

テストケースを作成して中身を記入していきます。

describeには一連の操作によって達成したい機能や処理の名前を記述します。
contextにはテストの内容を状況ごとに分類するために利用します。
itには末端のテストケースを記入します。
beforeにはitを実行する前にbeforeのブロックに書かれたコードを実行します。

require 'rails_helper'

RSpec.describe "Users", type: :system do
  let(:user) { create(:user) }

  describe 'ログイン後' do
    before { Login_as(user) }
    describe 'ユーザー編集' do
      context 'フォームの入力値が正常' do
        it 'ユーザーの編集が成功する' do
          visit edit_user_path(user)
          fill_in 'Email', with: 'test@example.com'
          fill_in 'Password', with: 'test'
          fill_in 'Password confirmation', with: 'test'
          click_button 'Update'
          expect(current_path).to eq user_path(user)
          expect(page).to have_content "User was successfully updated."
        end
      end
    end
  end
end

分量が多いのでテストケースを一つだけ用意しました。

  • let(:user) { create(:user) }はFactoryBotで定義したuserを使用しています。letを使うことで、最初にメソッドが呼ばれたときに評価されます。ここではLogin_as(user)で呼ばれています。※let!を使うと各itが実行される直前に評価されます。
    またcreate_listメソッドを使うと複数のインスタンスをまとめて作成することもできます。
let(:user1) { create(:user) }
let(:user2) { create(:user) }
 #このように書き換えることもできます。
=> users = create_list(:user, 2)
  • before { Login_as(user) }でlogin_module.rbで定義したLogin_asメソッドを使用しています。

  • fill_inclick_buttonexpect(page)などはcapybaraが用意しているメソッドです。
    参考 : Capybaraメモ - Qiita