はじめに
先日もお伝えしたとおり、電子書籍「Everyday Rails - RSpecによるRailsテスト入門」はRails 5.1とRSpec 3.6に対応しました。
ただし、RSpecについては現在すでにバージョン3.7がリリースされています。 RSpec 3.6と3.7は機能的な差異はほとんどないのですが、一点だけ、「システムスペック」という新しいタイプのテストが増えています。
このシステムスペックについて、原著者のAaronさんがご自身のブログで紹介されているので、その内容を翻訳してみました。 Everyday Railsの読者の方は(もちろんそれ以外の方も)ぜひ参考にしてみてください。
RSpec 3.7.2へのアップグレードとシステムスペック
原文: Upgrading to RSpec 3.7.2 and system specs | Everyday Rails
数ヶ月前(それはまさに、私がRails 5.1とRSpec 3.6に対応した「Everyday Rails - RSpecによるRailsテスト入門」の改訂版をリリースした数日後です)、RSpecチームは新たにバージョン3.7をリリースしました。本書の各章の内容はインクリメンタルに積み上げられていくことと、 rspec-rails gemは最初の方で本書のサンプルコードに導入されることから、本書の内容を無理に書き換えないことにしました。そのかわり、ここでは私が本書のサンプルアプリケーションをRSpec 3.7に対応したときの体験談をみなさんに共有します。この話の一番重要なポイントは、 Rails 5.1のシステムテスト(system test)がサポートされたということです。
システムテストが導入されたことにより、Railsフレームワークでは本書の第6章で説明したフィーチャスペックのように、ブラウザ上で実行するエンド・ツー・エンドのテストをデフォルトで書けるようになりました。このテストは システムテスト と呼ばれています。個人的な意見ですが、この種のテストはRailsのデフォルト機能として早く実装してほしいと、ずっと望まれていたように思います。私はRailsチームがシステムテストをシンプルに設定でき、なおかつシンプルに書けるように頑張ってくれたことに大変感謝しています(私のように、Railsアプリケーションのテストの書き方を教えている人にとっては、ちょっと仕事が増えてしまいますが!)。
ご存じかもしれませんが、RailsはデフォルトのテスティングフレームワークとしてMinitestを採用しています。しかし、RSpec 3.7を使えば、Rails 5.1のアプリケーションに対してシステムスペック(system spec)をテストスイートに追加できます 。RSpec 3.7は5.1より古いバージョンのRailsでも動きますが、その場合は統合テストとしてフィーチャスペックを使い続ける必要があります。もしかすると、みなさんはRails 5.1のシステムテストで提供されている機能のいくつかを使いたいと思うかもしれません。ですが、後述するような代替案も存在します。
アップグレード方法
私はこの手順の各ステップをそれぞれ独立したコミットにしています。よかったら、このコミットを見ながら進めてください。このアップグレードの準備を進めている際、私は
jquery-rails
とrspec-rails
が、お互いの依存関係からコンフリクトする問題に遭遇しました。そのため、このチュートリアルを執筆する目的で、私はRailsのパッチバージョンをアップグレードしています。
RSpecをアップグレードする前に既存のスペックを実行し、全てのスペックが期待どおりパスすることを確認してください。しばらくさわっていないプロジェクトの場合、この手順はとくに重要です。テストスイートが全てパスしたら、プロジェクト内の Gemfile に書かれたgemのバージョンをアップグレードします。
group :development, :test do gem 'rspec-rails', '~> 3.7.2' # 他のgemが並ぶ ... end
bundle update rspec-rails
を実行すると、インストールが完了します。場合によっては、ここで作業を止めることもできます。フィーチャスペックはRSpec 3.7でも動かすことができますし、しばらくはこれまで通り使い続けられるはずです。しかし、本書のテストスイートは積極的に新しくしていきたいので、既存のフィーチャスペックをシステムスペックに移行していきましょう。
最初は spec/support/capybara.rb
にある、テストドライバの設定変更をお勧めします。ブラウザを使った基本的なテストでは高速な Rack::Test
ドライバを使い、より複雑なブラウザ操作が必要な場合はJavaScriptが実行可能なドライバ(私はヘッドレスChromeを使うのが好きです)を使うように設定します。ファイルの内容を次のように変更してください。
RSpec.configure do |config| config.before(:each, type: :system) do driven_by :rack_test end config.before(:each, type: :system, js: true) do driven_by :selenium_chrome_headless end end
driven_by
の設定はテストごとに変更することもできます。ですが、私は可能な限りシステム全体の共通設定とします。
では、既存のフィーチャスペックを新しいシステムスペックの構造と構文に移行していきましょう。必要な変更は以下のとおりです。
spec/features
をspec/system
にリネームします。(diff)- 各ステップのtypeを
type: :system
にします。(diff) RSpec.feature
の代わりに、システムスペックを定義するRSpec.describe
を使います。(diff)- フィーチャスペックで使っていた
scenario
エイリアスを、標準的なit
構文に置き換えます(この変更は任意のようです)。(diff)
以上です!スペックは以前と同様にパスします。さらにこのあと、新しい統合テストを今回作成した spec/system ディレクトリに追加していくこともできます。
新しいシステムスペックを作成する
バージョン3.7.2の時点では、rspec-rails
はシステムスペックを作成するジェネレータを提供していません。ですが、私がこの記事を執筆している時点で、すでにプルリクエストが進行中です。ジェネレータが提供されるまでの間は、次のような定型コードを使用して手作業で新しいスペックファイルを spec/system ディレクトリに追加する必要があります。
require 'rails_helper' RSpec.system "Test name", type: :system do it "does something" do # ... your test end end
スクリーンショット
私たちがCapybaraを使い始めたときから、ブラウザベースのテストでは save_screenshot
メソッドを使って、実行中のテストのスクリーンショットを保存することができました。Rails 5.1とRSpec 3.7では代わりに take_screenshot
メソッドを使い、テスト内のあらゆる場所でシミュレート中のブラウザの画像を作成することができます。画像ファイルはデフォルトで tmp/screenshots に保存されます。また、テストが失敗したら、自動的にスクリーンショットが保存されます!この機能はヘッドレスブラウザで実行している統合テストをデバッグするのに大変便利です。
Rails 5.1を使っていない場合は、同じような機能を capybara-screenshot gemを使って実現できます。多少のセットアップは必要になりますが、このgemはRails 5.1がデフォルトで提供している機能よりも、さらに充実した機能を備えています。
Database Cleaner
本書のRails 5.1版では、Database Cleanerの説明を削除しました。なぜなら、これがなくてもサンプルアプリケーションのテストが動くようになったからです。しかし、以前のバージョンのRailsとRSpecからアップグレードした場合、みなさんはテスト間でデータベースの状態が予期せず共有されてしまわないよう、このツールを使い続けているかもしれません。Rails 5.1ではDatabase Cleanerはもう必要ありません。少なくとも、私の経験と私がこれまでに読んだ情報の上では不要になっています。もしみなさんが例外的な状況に遭遇したら、ぜひコメントを残して教えてください(訳注:日本語のフィードバックはこちらにお願いします)。
さらに前進する
RSpecのドキュメントではフィーチャスペックよりもシステムスペックを使うように推奨しています。この方針は合理的なものだと感じます。少なくとも、実際に私が既存のフィーチャスペックを新しいシステムテストに移行した経験上、そう思います。私は、みなさんが他のタスクよりも優先度を上げてこの変更に取り組む必要があるとは思いません。ですが、もし時間があればやってみてください。私はこの新機能を隅から隅まで試したわけではありませんが、これはあなたにとってCapybara gemをアップデートするいい機会にもなるかもしれません。特に、エラーや非推奨の警告(deprecation warning)に遭遇した場合は、きっとアップデートが必要になるでしょう。
みなさんが自分のRailsアプリケーションをシステムスペックに移行した際に経験したことをぜひ聞かせてください。ポジティブな話でもネガティブな話でも結構です。コメント欄はこの下にあります(訳注:英語版ブログの話です)。みなさん、いつも読んでくれてありがとうございます!
参考文献
(翻訳ここまで)
まとめ
というわけで、このエントリではEveryday Railsの原著者であるAaronさんのブログ記事を翻訳してみました。 システムスペックを導入してみたいと考えている方はぜひ参考にしてみてください。
Everyday Railsは今後もできるかぎり最新のRailsとRSpecに追従していきますので、引き続き「Everyday Rails - RSpecによるRailsテスト入門」よろしくお願いします!
Everyday Rails - RSpecによるRailsテスト入門 | Leanpub
「Everyday Railsって何?」「いったいどんな本?」と思われている方は以下のブログ記事をご覧ください。