Rails
RSpec
Selenium
Capybara

RspecとCapybaraを使ったフィーチャーテストで困ったこととその解決策いくつか

はじめに

最近、先輩や後輩と一緒にとあるポッドキャストのHPを作成しているのですが、先日フィーチャーテストを導入しました。
その際、環境構築やテストの書き方で困ったので、今後フィーチャーテストを始める人のために(そして未来の自分のために)、今回やったことをまとめます。

フィーチャーテストとは

「ブラウザ上でユーザーが実行する、ある目的を達成するための一連の動作のテスト」のことです。
「E2Eテスト」や「フィーチャースペック」と書かれていることもありますが、この記事では「フィーチャーテスト」とします。

目次

  • 関連するgemのインストールとセットアップ
  • 詰まったこととその解決策
  • 参考にした記事

バージョン

  • ruby 2.4.2
  • rails 5.1.4
  • rspec-rails 3.7.1
  • capybara 2.18.0
  • selenium-webdriver 3.10.0
    • ChromeDriver 2.36

関連するgemのインストールとセットアップ

以下の2つの記事を参考に初期設定を行いました。
【暫定版】Rails 5.1のSystemTestCaseでHeadlessモードのChromeを使ってみる - Qiita
Rails 5.1のSystemTestCaseを試してみた - Qiita

最終的な変更箇所は以下のとおりです。

Gemfile
group :development, :test do
  gem "capybara"
  gem "rspec-rails"
  gem "selenium-webdriver"
end
/spec/rails_helper.rb
args = %w[headless disable-gpu window-size=1920,1080] 
caps = Selenium::WebDriver::Remote::Capabilities.chrome(chromeOptions: { args: args })
Capybara.register_driver :selenium do |app|
  Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: caps)
end

window-size=幅,高さを変更することで、実行時のブラウザのサイズを変更できます。

また、ダウンロードしたchromedriverは/usr/local/bin/に置きました。
パスが通っているディレクトリならどこでも問題ないです。

詰まったこととその解決策

リンクでもボタンでもない要素をクリックする

find("div.hoge#fuga").click

fugaというidとhogeというクラスを持ったdivをクリックする場合はこう指定します。

複数の属性を指定して要素を取得する

find("input[type=text][name=nickname]")

もちろん、have_selectorと一緒に使うこともできます。

expect(page).to have_selector "input[type=text][name=nickname]"

セレクタに複数の要素が一致する場合に、任意の要素を指定する

page.all("セレクタ")[1].click

こうすればできますが、デザインの変更に弱いので、適切なidやクラスをつけることも検討したほうが良さそうです。
Tips:テストしにくいviewはテストをしやすいように変更する

スクリーンショットを撮影する

page.save_screenshot File.expand_path("/パス/ファイル名.拡張子", __dir__)

ローカル環境ではテストが通っても、CI環境だと通らないことがありましたが、そういうときにも役に立ちます。
CircleCIでスクリーンショットを保存する場合は、.circleci/config.ymlで設定したディレクトリに保存する必要があります。
参考: Storing and Accessing Build Artifacts - CircleCI

テストの前にシードデータを生成する

rails_helper.rb
config.before :suite do |_|
  fixture_path = Rails.root.join("db", "fixtures")
  SeedFu.seed(fixture_path)
 end

このプロジェクトではseed_fuを使用しているので、先述のgemのインストールとは別にseed_fuのインストールが必要です。
参考: mbleigh/seed-fu

セレクタに一致する要素の数をテストする

expect(page).to have_selector("セレクタ", count: count)

以上です。

いかがでしたでしょうか?
また新しく学んだことがあれば随時更新していきます。

誰かのお役に立てれば幸いです。

参考にした記事

使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」 - Qiita
使えるRSpec入門・その4「どんなブラウザ操作も自由自在!逆引きCapybara大辞典」 - Qiita
【暫定版】Rails 5.1のSystemTestCaseでHeadlessモードのChromeを使ってみる - Qiita
Rails 5.1のSystemTestCaseを試してみた - Qiita
Module: Capybara — Documentation for jnicklas/capybara (master)