統合テスト (System Spec)
この節では、前回作成したトップページ (Home#top) の統合テストを作成します。
Capybara について
統合テストはユニットテストと異なり、アプリケーション全体システムとして期待通りに動くことを確かめるためのテストです。
(RSpec においては統合テストのことを System Spec という呼び方をすることがあります。)
統合テストでは Capybara という gem を使用します。
Capybara は Rails 5.0 以降であれば最初からインストールされており、実際、Gemfile を見ると最初から書かれているはずです。
Gemfile
group :test do
# Use system testing [https://guides.rubyonrails.org/testing.html#system-testing]
gem 'capybara'
Capybara を使うと例えば「フォームに文字を入力し、送信ボタンを押す」というような、実際に画面を操作する流れに沿ったテストを直感的に書くことができます。
Capybara の基本メソッド
Capybara には多くのメソッドが備えられていますが、よく使うメソッドは一部ですのでここで紹介しておきます。
基本メソッド(操作)
本カリキュラムでも一部は登場しますので、使いながら覚えていきましょう。
visit
- 書き方:
visit '遷移したいページのパス'
- 実行される操作:指定したページに遷移
click_link
- 書き方:click_link 'リンク文字列'
- 実行される操作:指定したリンク文字列を持つ a タグ(リンク)をクリック
fill_in
- 書き方:`fill_in 'ラベル文字列', with: '入力したい文字列'
- 実行される操作:「入力したい文字列」を指定のフォームに入力
click_button
- 書き方:
click_button 'ラベル文字列'
- 実行される操作:指定したラベルを持つボタンをクリック
基本メソッド(結果確認)
page
visit
でアクセスした時、表示されるページの内容を取得します。
have_content('xxx')
という構文で、ページ内に特定の文字列が含まれているかどうかを確認するといった使い方があります。
current_path
現在のパスを取得します。
例えば、ログインしていないユーザーは別のページへリダイレクトするような動作を検証したい時、正常にリダイレクト先のページへ遷移したかどうかを確認する時に使います。
Home#top の統合テスト
それでは実際に Home#top、つまりトップページを表示する機能の統合テストを作成してみましょう。
とはいってもまだフォームもボタンも何も用意していないので、アクセスした時に期待した文字列 (view ファイルに書かれている文字列)が表示されることの確認だけします。
System Spec ファイル作成
統合テスト(System Spec)ファイルはrails g rspec:system ファイル名
という形式のコマンドで雛形を作成することができますので、実行してみましょう。
$ bundle exec rails g rspec:system home
create spec/system/homes_spec.rb
動作に支障はないのですが名前が homes_
になっているので、統一のためにhome_
にリネームしておきます。
$ mv spec/system/homes_spec.rb spec/system/home_spec.rb
では、生成されたファイルを spec/system/home_spec.rb
の中身を確認してみましょう。
spec/system/home_spec.rb
require 'rails_helper'
RSpec.describe "Homes", type: :system do
before do
driven_by(:rack_test)
end
pending "add some scenarios (or delete) #{__FILE__}"
end
この段階でダブルクォーテーション ""
が含まれていたので、Rubocop の自動修正で直してしまいます。
$ bundle exec rubocop -a
さて、雛形の中身ですが、現在は pending となっているのでその部分のテストは実行されません。
試しにこのファイルだけテストを走らせてみます。
$ bin/rspec spec/system/home_spec.rb
...
Pending: (Failures listed here are expected and do not affect your suite's status)
1) Homes add some scenarios (or delete) .../spec/system/home_spec.rb
# Not yet implemented
# ./spec/system/home_spec.rb:8
Finished in 0.00121 seconds (files took 0.36953 seconds to load)
1 example, 0 failures, 1 pending
このように System Spec で pending
と書いておくと、そのテストはどんな内容を書いていても実行されません。
では次に、System Spec ファイルを修正していきます。
System Spec ファイル修正
Home#top の最低限のテストということで、以下のような最低限の動作だけテストします。
-
/
(トップページ) にアクセスする - ブラウザでアクセスした時と同じく
Home#top
という文字列が表示される
上記程度のテストであれば数行で済むので簡単です。
spec/system/home_spec.rb
を次のように書き換えてください。
spec/system/home_spec.rb
require 'rails_helper'
RSpec.describe 'Home', type: :system do
before do
driven_by(:rack_test)
end
describe 'トップページの検証' do
it 'Home#top という文字列が表示される' do
visit '/'
expect(page).to have_content('Home#top')
end
end
end
テスト実行
それでは System Spec を実行してみましょう。
編集したテストのみを実行するには、いつもの bin/rspec
に続いてファイル名を渡してあげます。
$ bin/rspec spec/system/home_spec.rb
...
Home
トップページの検証
DEBUGGER[rspec#44711]: Attaching after process 44690 fork to child process 44711
Home#top という文字列が表示される
Finished in 6.03 seconds (files took 0.33855 seconds to load)
1 example, 0 failures
0 failures
という表示、つまり失敗したテストが 0 件となっていることを確認してください。
今回はアクセス&表示内容の確認だけのテストでしたが、カリキュラムの後半ではフォームへの入力や、レコードが増えることの確認も行なっていきます。
ここまでの変更を一旦コミットしておきます。
$ git add .
$ git commit -m "トップページの統合テストを追加"
Headless モードへ変更
System Spec を実行した際、ブラウザが一時的に立ち上がって画面が表示されたことにお気付きでしょうか?
Capybara は実際にブラウザを使って画面の確認を行うため、そのような挙動になります。
しかし、毎回テストを走らせる度にブラウザが立ち上がるのは少々うるさく、ブラウザを立ち上げて描画する分、テストが遅くなります。
そこで Capybara を Headless モード で実行し、ブラウザを起動せずとも System Spec が走るようにしましょう。
Headless モードで実行するための設定は簡単でして、System Spec のテスト内容の前に Headless モードでの実行を指定してあげるだけです。
以下の 3 行を追記します。
spec/system/home_spec.rb
...
RSpec.describe 'Home', type: :system do
before do # ここから追記
driven_by :selenium_chrome_headless
end # ここまで追記
この状態で再度 System Spec を走らせます。
$ bin/rspec spec/system/home_spec.rb
...
Home
/home/top 画面の検証
DEBUGGER[rspec#47924]: Attaching after process 47918 fork to child process 47924
Home#top という文字列が表示される
Finished in 1.48 seconds (files took 0.34879 seconds to load)
1 example, 0 failures
今度はブラウザが立ち上がることなくテストが完了することを確認してください。
また、先ほどまでは 5~6 秒ほどテストにかかっていましたが、今度は 1~2 秒程度で終わるようになっています。
統合テストは一つひとつの実行に時間がかかるため、今後増えてきた時のためにも高速化の工夫が重要になってきますので、覚えておきましょう。
変更をコミット
ここまでの変更をコミットし、リモートリポジトリに同期して今回は終わりです。
$ git add .
$ git commit -m "HomeのSystem SpecをHeadlessモードで実行するように変更"
$ git push
宿題
Capybara の便利なメソッド集
本カリキュラムで使用&紹介する Capybara のメソッドはごく一部ですが、紹介しないメソッドでも使い所があり、有用なものが多くあります。
他にはどのようなメソッドがあるかや、便利なテクニックについての全体像だけでも知っておくと後で役立ちますので、こちらのサイトを目次だけでも一度は読んでおきましょう。