ついにE2Eテストが書けるようになったんだけど、道のりが長過ぎた
るびまや先人たちのブログを参考に、Turnipなどを使ってエンドツーエンドテスト(E2Eテスト)を書く環境を整えました。
Turnipってなに?
これです。
というのは冗談で、冒頭にあげた通りE2Eテストを自動化するツールです。ちなみにこの手のライブラリの先輩であるキュウリ…じゃなかったCucumberの問題点を解決したとかしないとか*1。
必要なライブラリの簡単な紹介
何かといろいろライブラリがいるので、それもまとめてご紹介します。
- RSpec
- もはや説明不要のテストツールです。別にTest::Unitでもいいんでしょうけど、こちらの方が相性がよさそうなのと、私も書き慣れているのでこちらを使います。
- Gherkin
- テストシナリオを記述するための言語を操作するライブラリです。うまくやるとかなり自然な日本語でもテストシナリオが書けます*2。
- Capybara
- ブラウザの UIを自動で操作したり、結果を確認したりするためのAPIを提供するライブラリです。
- PhantomJS
- JavaScriptドライバです。デフォルトのSeleniumでもよかったのですが、最近いい感じらしいとのことなので今回はこちらを選択。
使えるようになるまで
ひとまずRailsで使えるようにしてみましょう。
まずはGemfileに以下のように書きます。
group :test do gem 'rspec' gem 'capybara' gem 'launchy' gem 'poltergeist' gem 'turnip' end
bundle installする前にPhantomJSをインストールしましょう。さもなくばpoltergeistのインストールでこけます。
次に、spec_helper.rbにrequireを追加します。
Dir.glob("spec/**/*steps.rb") { |f| load f, true } require 'capybara/dsl' require 'capybara/rspec' require 'capybara/poltergeist' require 'rspec/rails' require 'rspec/autorun' require 'turnip' require 'turnip/capybara'
これでひとまず準備はできました。
テストの書き方
Turnipを使ったテストは、
- シナリオを記述するファイル(慣例的に*.featureという名前にする)
- シナリオの動作や正誤判定を記述するファイル(慣例的に*_step.rbという名前にする)
の2つを使います。以降それぞれをフィーチャーファイル、ステップファイルと称します。
今回はわかりやすフィーチャーファイルをspec/features、ステップファイルをspec/steps以下においていきます。
フィーチャーファイルの書き方
まずはフィーチャーファイルから見ていきましょう。
今回は簡単に
spec/features/login.feature
というファイルを作りましょう。
中身はいろいろな言語で書けますが、今回は日本語で以下の通り書きます。
# encoding: utf-8 # language: ja #↑この行がないと英語で書くことになります。この行はコメントです。 機能: ユーザー認証 シナリオ: ログイン画面を表示する 前提 サイトにアクセスする もし トップページを表示した ならば ログインフォームが表示される
2行目でどの言語なのかを指定しています。日本語で書くときは上の通り「# language: ja」と書いておきましょう。
それから、肝心なのは行頭です。上の例だと「機能:」「シナリオ:」、それ以外で役割が違って、
- 機能:
- 機能全体の説明
- シナリオ:
- 機能に数あるうちの使い方のうちのひとつ
- それ以外
- 作業手順や動作手順ひとつひとつ
というふうになっています。「前提」とか「ならば」とかいろいろあるのは、文脈に応じて自然な感じになるように使い分けられるようにするためだとか。
ステップファイルの書き方
次はステップファイルを見てみましょう。
こちらは「spec/steps/login_spec.rb」という名前にしておきます。対応するフィーチャーファイルとステップファイルの名前をそろえておきましょう。
#coding utf-8 step 'サイトにアクセスする' do Capybara.app_host = "http://localhost:3000" end step 'トップページを表示した' do visit '/' end step 'ログインフォームが表示される' do expect(page).to have_content('ログイン') end
見ての通り、作業手順や動作結果ひとつひとつ対応した、stepというメソッドを書いていきます。そして、ブロックの中身にアサーションや動作を記述していきます。
テストの実行方法
今回は、Railsのプロジェクトルートで、
$bundle exec rspec -r turnip/rspec spec/features/login.feature
と打ち込むと個別に実行できます。