Rails3 Rspec で(いい加減な)エンドツーエンドテストを書いてみる

次に画面をまたいだ動作テストを行います。

ブラウザの挙動をシミュレートして、表示される画面やボタン操作などをテストできます。

Capybara の導入

Gemfile へ capybara を追記/インストールします。

gem 'capybara'
bundle update

インストールが完了したら、spec_helper.rb の中で require します。

require 'capybara/rails' # <- spec_helper.rb に追記

準備完了。テストコードは spec/requests 以下に配置していきます。

テストケースの記述

新規登録フォームにアクセスし、フォームに名前を入力し、それをポスト。
完了画面にて、表示されるべき文字列が表示されているか、という一連の流れをテストするコードを書きます。

describe 'when create new employee,' do
 it 'should be create an employee.' do
   visit new_employee_path
   # rendered /employee/new
   fill_in 'employee_name', :with => '薬院加奈子'
   click_button 'Create Employee'
   # rendered /employee/1
   page.should have_content 'Employee was successfully created.'
   page.should have_content '薬院加奈子'
 end
end

visit メソッドは渡されたパスへアクセスします。

new_employee_path なので、新規登録入力画面へ遷移しているのをシミュレートしています。

画面が表示されたと(想定)して、フォームに文字列を入力するシミュレートをします。

fill_in メソッドでフォームに値をセットして行きます。

fill_in メソッドの第一引数に対象としたいフォームの id / name / label を指定します。

今回の場合、scaffold によって作られた employees/_form.html.erb のなかで

<%= f.text_field :name %>

として記述され、

<input type="text" size="30" name="employee[name]" id="employee_name">

としてレンダリングされるので、ここでは id で見つけるために、’employee_name’ を渡します。

そして、そのフォームに対して値を設定するには代に引数に { :with => ‘薬院加奈子’ } というオブジェクトを渡します。

これで、id が employee_name のフォームに、”薬院加奈子” という文字列を入力したことをシミュレートしています。

click_button はその名の通り、ボタンをクリックすることをシミュレートしています。

渡している引数は、ボタンを指定するための value の値です。

指定できるのは、id / value / text です。name ではできないのがなんだか微妙な、何か理由があるのか、ちょっと不満です。

(_form.html.erb では name=”commit” で定義されているので、’commit’ で見つけられるとよさそうなモンですが…)

この二行で、フォームに名前を入力し、Submit ボタンをクリックする動作のシミュレートをしていることになります。

submit によってコンロトーラーのメソッドが動いて、結果画面が表示されました。つづいて結果画面を検証します。

submit のあとには登録されたユーザーで show アクションが動くので、表示された画面の検証をしています。

have_content メソッドで、現在のページに含まれる文字列を探します。

flash によって表示されるはずの文字列と、show アクションで表示されるはずの、登録した名前がページ内にあるかを検証します。

page.should have_content 'Employee was successfully created.'
page.should have_content '薬院加奈子'

have_content メソッドの戻りオブジェクトを should に渡して使います。

この二行は、バリデーションエラーもなく、レコードの作成に成功し、新しい Employee を表示する show アクションが表示されたページについて、チェックしたい文字列が存在する事をシミュレートしました。

非常に簡単にですが、MVCユニットテストとエンドツーエンドテストの作成を行ってみました。

異常ケースやエラーメッセージの検証などは書きませんでしたが、実際の開発ともなれば、バリデーションエラー時の挙動テストも必要でしょう。

仕様と操作なので、この程度ですが、もうちょっと複雑なアプリケーションともなるとテストコードはもっと膨大になるでしょうね…。

しかし、大抵の場合、テストコードが大きい = アプリケーションの規模も大きい ことになるでしょうから、一度キチンと書いておけばリファクタリングや機能追加によるレグレッションもすぐに発見できるし、やっぱりテストコードを書く事は大事ですね。

ただし、テストコードもきちんとメンテナンスしない事にはただ無駄なコードを生産するだけになってしまうので、テストコード自体の品質にも意識をしないといけないですね。

参考サイト

以下、Rspec でテストコードを書く参考に良さそうなサイト

シェアする

  • このエントリーをはてなブックマークに追加

フォローする