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_in
やclick_button
、expect(page)
などはcapybaraが用意しているメソッドです。
参考 : Capybaraメモ - Qiita