Chapter 09

2-6. 統合テスト (System Spec)

Masuyama
Masuyama
2022.10.15に更新

統合テスト (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 'リンク文字列'
  • 実行される操作:指定したリンク文字列を持つ 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 の最低限のテストということで、以下のような最低限の動作だけテストします。

  1. / (トップページ) にアクセスする
  2. ブラウザでアクセスした時と同じく 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 のメソッドはごく一部ですが、紹介しないメソッドでも使い所があり、有用なものが多くあります。

他にはどのようなメソッドがあるかや、便利なテクニックについての全体像だけでも知っておくと後で役立ちますので、こちらのサイトを目次だけでも一度は読んでおきましょう。