話題のテストツール Steak を勉強してみた
以前 Ruby on Railsの達人 @a_matsuda に 薦められた テストツール Steak を現在開発中のプロジェクトで使ってみようと思い、勉強してみました。
Steakとは
Steak は Cucumber 同様に Ruby on RailsなどのWebアプリの受け入れテストや総合テストのツールです。Cucumberは仕様(テスト)を自然言語で記述できるのが大きな特徴でしたが、SteakではRSpec+専用DSLで記述しまます。
Cucumberは仕様(テスト)を自然言語で書けるので、ユーザーに仕様を確認してもらうとか作ってもらえるのが最大のメリットです。しかしその分、feature(仕様)とStep(仕様をプログラムをつなぐコード)の2つを記述する必要あり開発の手間が取られます。
それに比べ、 Steak は RSpec (= Rubyのコード) なので、プログラマーに取っては、読み書きは容易です。
受け入れテストや総合テストでは表示結果(html) を確認するコードが必要になりますが、 Steak では Capybala を使い CSSセレクターでhtmlの要素を指定できるので簡潔な記述が出来ます。
CSSセレクターは、デザイナーではないプログラマーでもjQuery等でも使われているのでお馴染みだと思います。
インストール
インストールは Steak ページに書かれているように bundle (Rails3)なら簡単です。
1. Gemfileに以下を追加し、 bundle install を実行
group :test, :development do gem "rspec-rails" gem 'steak' gem 'capybara' gem 'spork' end
2. プロジェクト内で以下の初期化コマンドの実行
$ rails g rspec:install $ rails g steak:install
後は rails generate steak:spec コマンドで feature(仕様)ファイルを作り、そこにコードを書いて行きます
テスト対象の作成
勉強なので簡単なプログラムということで scaffold で出来たコードをテストしてみる事にしました。
$ rails new todo_steak -T $ cd todo_steak $ rails g rspec:install $ rails g steak:install $ rails g scaffold todo due:date task:string $ rake db:migrate $ RAILS_ENV=test rake db:migrate $ vi spec/fixtures/todos.yml <= テストデータの作成 ----------- todo01: due: 2011-02-18 task: 打ち合わせ todo02: due: 2011-02-20 task: 開発 ----------- $ rake db:migrate $ RAILS_ENV=test rake db:migrate $ vi app/models/todo.rb <= validation の追加 ------------ class Todo < ActiveRecord::Base validates_presence_of :task end ------------ $ vi app/controllers/todos_controller.rb ------------ @todos = Todo.all ↓ <= ソート指定 @todos = Todo.order(:due).all ------------
テストコード
1. 一覧表示機能 spec/acceptance/list_feature_spec.rb
require File.expand_path(File.dirname(__FILE__) + '/acceptance_helper') feature "Todo一覧の表示" do fixtures :todos scenario "Todo一覧が表示できる" do visit list_page page.should have_css("h1", :text => "Listing todos") page.all("table tr:eq(2) td")[0..1].map{|e| e.text}.should == ["2011-02-18", "打ち合わせ"] page.all("table tr:eq(3) td")[0..1].map{|e| e.text}.should == ["2011-02-20", "開発"] end end
scenarioに仕様(テスト)を書きます。
- vist list_page はでistページをアクセス
- list_page は spec/acceptance/support/paths.rb で具体的なURLを定義しています
module NavigationHelpers def list_page "/todos" end def new_page "/todos/new" end end RSpec.configuration.include NavigationHelpers, :type => :acceptance
- page.should have_css("h1", … はページ上に Listing todos と書かれたh1タグが在ることを検証します
- 次の2行は
テストの実行は RSpec なので spec コマンドや rake spec です。
2. 新規作成機能 spec/acceptance/new_feature_spec.rb
require File.expand_path(File.dirname(__FILE__) + '/acceptance_helper') feature "Todoの新規作成" do fixtures :todos scenario "Todoが新規作成できる" do visit new_page within "form" do select "2011", :from => "todo_due_1i" select "February", :from => "todo_due_2i" select "10", :from => "todo_due_3i" fill_in "Task", :with => "テスト" click_button "Create Todo" end page.should have_css "#notice", :text => "Todo was successfully created." Todo.count.should == 3 Todo.last.due.to_s.should == "2011-02-10" Todo.last.task.should == "テスト" end scenario "Taskが空ならエラーになる" do visit new_page within "form" do select "2011", :from => "todo_due_1i" select "February", :from => "todo_due_2i" select "10", :from => "todo_due_3i" fill_in "Task", :with => "" click_button "Create Todo" end page.should have_content "Task can't be blank" end end
最初の scenario は新規登録ページを表示し、フォームに入力しsubmitボタンを押すと成功しRDBにデータが出来ている事を検証しています。
- within "form" do でformタグ内を操作(検証)対象とします
- select "2011", :from => "todo_due_1i" は id が todo_due_1i のselectタグで 2011 を選択します
- fill_in "Task", :with => "テスト" は Task というラベルのinputフィールドに "テスト"と入力します。input タグの指定は id や name 対応する label などが使えます
- click_button "Create Todo" で Create Todo ボタンが押され、フォームの値がpostされます
- page.should have_css.... は成功メッセージが表示されている事を検証しています
- Todo.から始まる3行はTodoテーブルにフォームから入力した値でレコードが出来ている事を検証しています
つぎの scenario は入力エラーチェックの検証です。Taskフィールドに何も入力されてない場合はエラーが表示される事を確認しています
記述は、上とほぼ同じなので省略します。
Steak の感想
- Steak はRSpecなのでビューレベルの検証もモデルレベルの検証も同じように、同じファイルに書けるは嬉しいです
- RSpecなので spork と組み合わせるとテストの実行は高速です、開発時にはたいへん嬉しいですね
- CSSセレクターの :eq(n) は jQueryでは 0 から始まりますが、Capybara では 1 から始まります、合わせて欲しいですね
- Javascriptも含めテストできるという capybara-envjs を試したのですが、テストした jQueryのコードは動きませんでした。まだ開発途上らしいです。将来に期待しましょう !!
ということで、今回のプロジェクトでは Steak を使って 総合テストを書いてみようと思います。プロジェクトが終わったら、また Steak に付いて書きたいと思います。