ゆうなんとかさんの雑記帳的な。

Twitterで踊ったり音ゲーしたりしてるあの名前がよくわからない人が書いてるらしいよ。

ついにE2Eテストが書けるようになったんだけど、道のりが長過ぎた

るびまや先人たちのブログを参考に、Turnipなどを使ってエンドツーエンドテスト(E2Eテスト)を書く環境を整えました。

Turnipってなに?

これです。
http://www.heirloom-organics.com/images/polaroid/nonhybrid-turnip.gif
というのは冗談で、冒頭にあげた通り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

と打ち込むと個別に実行できます。

長い長い道のりでした

お疲れ様でした、といってもこれからなのですが…

*1:なんで揃いも揃って食べ物の名前なんだろう…

*2:自然さを追求すると英語で書き出しそうだけど