Ruby 系のプロダクトを使ってエンドツーエンドテストをしたい

## 動機
* 「目標(リンク/ボタン)を押下して確認」、「目標(リンク/ボタン)を押下して確認・・・」、「目標(リンク/ボタン)を押下して確認・・・・・・」× 複数ブラウザ、なんてやっていられないので、とある Web アプリのエンドツーエンドテスト(End to End test)を自動化することにした。

## どうやって実現しようかな
* 仕事では全然使っていないけれど、個人的に勉強している Ruby 周りで実現できれば、Ruby の実務経験にもなるから一石二鳥。
* でも、テスト対象アプリは Rails とかで作られているわけじゃない。
* 別に相関関係は無いから Ruby でやってもいいではないか。やってしまおう。

## 何を使って実現しようかな
インターネット様は偉大。下記のものを使ってみることにする。

* Turnip 
   * 受け入れテストのフレームワーク
   * 自然言語でのテストケース表現。実際のテストケースは Rspec に任せる
   * ポスト Cucumber

* Capybara
      * 受け入れテストのフレームワーク
      * ブラウザの UI 自動テスト時の便利な API 群

* Rspec
      * Ruby のテストフレームワーク
      * 他のテストフレームワークには Test::Unit、MiniTest というものがある

* Selenium-web-driver
      * ブラウザ/JavaScript ドライバ
      * 各種ブラウザを起動して操作することができる

## まずはテストを実施する環境をどうしようか考える
* ブラウザで Web アプリケーションにリクエストを送るのは Windows マシンにやってもらいたい(アプリ利用者が圧倒的に Windows 勢だから)
* Ruby 周りの環境整備で Windows を使うとハゲるとじっちゃんが言っていたので、テストコードを実行する環境は Linux(CentOS) にすることにした。

## 上記のことを踏まえてこんな環境で実行することにした
* テストコードを実行する環境(※1)
	* OS
		* CentOS (バージョン忘れた)
	* Ruby 周り
		* Turnip 1.2.x
		* Capybara 2.2.x
		* Selenium-web-driver 2.42.0
		* Ruby 2.1.x
		* bundler 1.6.x
		* Rspec 2.14.x
* ※1 から呼び出されてブラウザでテスト対象 Web アプリにリクエストを送る環境
	* OS
		* Windows 7
	* ブラウザ
		* IE10
		* Firefox
		* Chrome

## 幸いにしてサーバ類の環境は既にあったので、テストの仕組みを早速作る
Ruby と bundler は既に入っていたので割愛します。
(Ruby は rbenv 等でバージョン管理できるようにしておいたほうが未来で幸せになれるかもしれません)

* 適当なディレクトリを掘り、そこに移動する

* bundler 用の設定ファイルを作成する
	* Gemfile

```ruby:Gemfile
group :development, :test do
	gem 'rspec-rails'
	gem 'capybara'
	gem 'turnip'
end
```

* bundle install を実行する

* rspec 用の設定ファイルを作成する(rspec 実行時のオプションを書いておく)
   * .rspec

```ruby:.rspec
--color
-r turnip
```

* テストコードの置き場所を作成する

Turnip 向けに書くテストシナリオと、Rspec　向けに書くテスト実装の置き場所

```
$ mkdir spec/features
$ mkdir spec/steps
```
* spec/spec_helper.rb を作成する
   * steps ファイルの置き場所を明示する
   * step.rb で使用するメソッドを定義する
   * 共通の設定等を定義する

```ruby:spec/spec_helper.rb
Dir.glob("spec/**/*steps.rb") { |f| load f, true }

require 'capybara/dsl'
require 'capybara/rspec'
require 'turnip'
require 'turnip/capybara'

Capybara.default_driver = :selenium
Capybara.ignore_hidden_elements = true
Capybara.run_server = false

# 以下はテストしたいブラウザごとの設定。リモートマシンのブラウザを起動するためのもの。
### Firefox
#Capybara.register_driver :selenium do |app|
#	Capybara::Selenium::Driver.new(# app,{browser: :remote, url: "http://xxx.xxx.xxx.xxx:4444/wd/hub"})
#end

### Chrome
#Capybara.register_driver :selenium do |app| 
#	Capybara::Selenium::Driver.new( 
#	app, {browser: :chrome, url: "http://xxx.xxx.xxx.xxx:9515"}) 
#end

### IE
#Capybara.register_driver :selenium do |app| 
#	Capybara::Selenium::Driver.new( 
#	app, {browser: :remote,desired_capabilities: :internet_explorer, url: "http://xxx.xxx.xxx.xxx:4444/wd/hub"}) 
#end
```

* features ディレクトリに Turnip　のテストシナリオファイルを置く

```ruby:features/ika.feature
# encoding: utf-8
# language: ja

機能:XXX を表示するシナリオ: XXX が正しく表示されていることを確認する
	前提 XXX にアクセスする
	もし XXX を表示する
	ならば XXX が正しく表示されている
```

* steps ディレクトリにテスト実装コード(Rspec)を置く

以下例だとリクエストしたページ内に「いか」という文字列があることを期待している。
ついでにスクリーンショットも取る。

```ruby:steps/ika_steps.rb
# encoding: utf-8

step "XXX にアクセスする" do
	Capybara.app_host = "http://xxx.xxx.xxx/"
end

step "XXX を表示する" do
	visit '/' 
end

step "XXX が正しく表示されている" do
	expect(page.to have_content('いか')
	page.save_screenshot 'screenshot.png' 
end
```

##　テストコードの準備は終わり。後はブラウザを起動する環境の準備をする

* 各ブラウザ向け　Selenium Server 用のファイルをダウンロードして、適当な場所に置く
	* http://www.seleniumhq.org/download/
		* chromedriver.exe
			* chrome 用
		* selenium-server-standalone-x.x.x.jar
			* Firefox, IE用(※ IE は下記 exe も必要)
		* IEDriverServer.exe

* Selenium Server を起動する(コマンドプロンプトで)
	* Chrome
		* C:\ika\chromedriver.exe
	* Firefox, IE
		* java -jar c:\ika\selenium-server-standalone-x.x.x.jar -Dwebdriver.ie.driver=c:\ika\IEDriverServer.exe

## いよいよテストコードを実行する
   * bundle exec rspec spec/features/ika.feature

テストの実行結果がオッケーっぽい表示になっていればよし。
(お作法的には最初にコケるテストを書いておいたほうがよさげ)

## お疲れ様でした
* 実際に動かしたコードを元に記事を書きましたが、スペルミス等で動かなかったらスイマセン。