この記事の内容
プロダクトの作成中、設定がいまいちだったためにシステムテストに徐々に不具合が出てくるようになった。リファクタリングをするとともに、システムテストについて今一度しっかり勉強して、ノートにまとめてみた。
対象読者は、今までコピペでテスト周りの設定をしていたけれど、それをしっかり理解しながら自分でやってみたい人。
システムテストを構成する要素
この記事はいくつかのパートに分かれていますが、前半のこの部分は、主にこちらの記事の内容をまとめたもの。
システムテストには、以下の三つの要素が必要とのこと。
-
テストランナー
... RSpec, Minitest など -
テストサーバー
... WEBrick, Puma など -
ブラウザー
... 後述
テスト用のブラウザについて
上記のうちブラウザについては、テスト用のブラウザもいくつか開発された。一方で、「現実のブラウザを使う」という体験に追いつくのは難しかった。
Seleniumとは
ブラウザの自動化テストで勝ち残ってきたソフトの一つ。ブラウザごとの差異に対応してテストを実施できた。
転機とCDP
ChromeがCDPプロトコルを提供して、ブラウザを直接操作できるようになった。
CDPを利用したプロジェクト代表例
このうちFerrumについては、以下の利点もある。
- Pupetterとの互換性も保たれている。
- Cuprite(CupriteはピュアRuby製Capybaraドライバ、CDP使用)も同梱されている。
WebDriverとは
WebDriverとは本来はプロトコルらしい(ソースはこちらの記事)。そして、そのプロトコルを使って操作をするのが、WebDriverToolであるとのこと。
主要ブラウザごとに
- Chrome ...chromedriver
- Firefox ... geckodriver
- MS Edge ... edgedriver
- Safari ... safaridriver
があるそう。
Rails6
では、デフォルトでそれらをまとめてwebdrivers
というGemでDLしてくる。そして、Capybara
のデフォルトの設定でそれを使うようになっている。
WebDriverとSelenium-Webdriber
WebDriverはそれが呼び出された時に、Selenium-Webdliver
を拡張して呼び出す。
ブラウザごとに最新のWebDriverツールをDLしてきて、それらがSelenium-Webdliver
で使えるようにする。
システムテスト関連の、設定ファイルの読み方
このように、システムテストには色々なツールが関わっている。
そして、「色々なツールが関わっている」ためにシステムテストの設定ファイルを読み解くのが、当初は少し難しかった。
例えば、こんなコードがあったとする
Selenium::WebDriver::Remote::Capabilities.chrome( ... )
Capybara::Selenium::Driver.new( ... )
この時、1行目はSelenium
の設定で、2行目はCapybara
の設定になる。
上記で、.chrome
はSelenium
の下位クラスのメソッドで、や.new
はCapybara
の下位クラスのメソッド。
つまり、機能の詳細を知りたいときは一番左に書いてある名前のもののドキュメントを見れば良いのだが、どれも同じような名前なので、最初はとてもわかりにくかった。
ちなみに、参考にしたドキュメントはこちら。
なお、設定ファイル中に、こんな記述もよく出てくると思う。
RSpec.configure do |config|
config.fixture_path = "#{::Rails.root}/spec/fixtures"
# さまざまな設定が続く ...
end
この時のconfig
はブロックを囲んでいるRspec
の設定で、fixture_path
はRspecのメソッド。こちらも似たような記述が多いので、今、何の設定をしているのかを見失わないように注意。
rails_helper と spec_helper
設定ファイルを書く場所には rails_helper
とspec_helper
がありますが、基本的にはrails_helper
に書けば良さそう。
-
spec_helper
... Railsに依存しないSystem Testを書くためのファイル -
rails_helper
... RailsにおけるSystem Testの設定を書くためのファイル
らしいのだけど(参考:「RSpec 3 時代の設定ファイル rails_helper.rb について」)、あまりRailsに依存しないsystem specを書く人はいないと思うので。。。
rails_helper
の自動生成されるコードを見ても、上の方に
require 'spec_helper'
と入っている。spec_helper
の設定を読み込んでからrails_helper
を動かしているのがわかる。
そして、それぞれのspecファイルでは
require 'rails_helper'
RSpec.describe 'SomeModelSpec', type: :model do
# ...
end
というように、rails_helper
を読み込んでいるので、両者の設定が反映される。
ちなみに、どちらかの設定ファイル(大概rails_helper
)にこのような記述があれば
Dir[Rails.root.join('spec/support/**/*.rb')].sort.each { |f| require f }
これはspec/support
ディレクトリ下にある設定も読み込むということなので、そちらの設定も確認する。
余談:Systemテストになって不要だったもの
なお、システムテストに関しては古い記事もたくさんあり、コピペでなんとなく導入していたら、実際には不要になったものもたくさんあった。
system specが導入された当時に、その新機能を紹介した記事はこちら。
システムテストでは、「データベースのロールバック」「テストが失敗したときのスクリーンショット自動撮影」など機能が備わっているので、もし、以下の導入を紹介する記事があったら、それらは基本的には不要です。
- capybara-screenshot ... capybaraでscreen shotをとってくれるGem
- database_cleaner ... テスト後、データベースの掃除をしてくれるgem
以上、まとまらない内容ですが、システムテストの設定ファイルをしっかり読みたい人の助けになればと思います。。。