l'essentiel est invisible pour les yeux

Monday, November 06, 2006

[Rails] RSpec on Railsを始めてみた - インストールと実行

RSpec on Railsのさわりだけ。

おそばせながら今頃、BDD(Behaviour Driven Development)を知りました。。。
これからはきちんとBDD or TDDで開発を進めます。

BDDはテスト駆動開発と言葉の言い回しが大きく異なっている。
「ベヒイビアを書いて仕様を設計する。」これが大きなポリシー。
BDDでは必ず仕様コード(spec)を書いてから実際のコーディングを行う。


Rubyには、RSpecというツールがありこれを利用する。
gemパッケージが用意されているので簡単。


$ gem install rspec


次にRSpec on Railsプラグインをインストール。
REL_X_Y_Zの部分をrspecのバージョンとあわせる必要がある。

$ cd RAILS_ROOT
$ ruby script/plugin install svn://rubyforge.org/var/svn/rspec/tags/REL_0_6_4/vendor/rspec_on_rails/vendor/plugins/rspec


RSpecでは、spec/ディレクトリ以下にspec, fixturesファイルなどが展開される。
始めにこのディレクトリを作成する。


$ ./script/generate rspec


インストール終わり。

テストの実行方法がいくつか用意されている。

rakeを使用する場合
  1. 全てのビヘイビアを実行
  2. コントローラのベヘイビアを実行
  3. モデルのビヘイビアを実行
それぞれ、

$ rake spec
$ rake spec:controllers
$ rake spec:models

で実行可能。

単体でも仕様を検証可能
単体で仕様(ビヘイビア)を満たすか検証することも可能。
先にscript/rails_spec_serverというプログラムを起動しておく。(Railsの環境設定が読み込まれるため実行が早くなる)

次の例では、personモデルの仕様を検証している。

$ ./script/rails_spec_server
$ ./script/rails_spec spec/models/person_spec.rb


コントローラー・モデルの作成
RSpecには、Specも同時に生成してくれるジェネレータが定義されている。
それぞれ、

$ ./script/generate rspec_controller index
$ ./script/generate rspec_model person

として利用でき、


create spec/controllers/
create spec/views/index
create spec/controllers/index_controller_spec.rb
create spec/models/
create spec/fixtures/
create spec/models/person_spec.rb
create spec/fixtures/people.yml

といった感じで通常のジェネレータに加えて、(モデル名 | コントローラ名)_spec.rbというファイルなどを生成してくれる。

仕様(べヘイビア)を書く
Personモデルを作成して、spec/models/person_spec.rbを編集して仕様を定義した。

require File.dirname(__FILE__) + '/../spec_helper'

context "Person class with fixtures loaded" do
fixtures :people

specify "should count two People" do
Person.should_have(2).records
end

specify "should full name is 'first_name last_name'" do
person = Person.find(1)
person.full_name.should_equal "#{person.first_name} #{person.last_name}"
end
end


app/model/person_spec.rbにメソッドを定義
class Person < ActiveRecord::Base
def full_name
"#{self.first_name} #{self.last_name}"
end
end

テスト実行
別ターミナルでscript/rails_spec_serverを実行しておく。

[4246]% ./script/rails_spec spec/models/person_spec.rb [/var/www/test]

..

Finished in 0.114999 seconds

2 specifications, 0 failures
[4248]%

この二つの仕様は正しいのでピリオドが二つ出力された。
仕様(spec)の数だけピリオド(またはF)が出力される。

should_equalをshould_not_equalに書き換えて、意図的に失敗させた場合は、次のように出力される。

[4237]% ./script/rails_spec spec/models/person_spec.rb [/var/www/test]

.F

1)
Spec::Expectations::ExpectationNotMetError in 'Person class with fixtures loaded should full name is 'first_name last_name''
"rakuto furutani" should not equal "rakuto furutani"
./spec/models/person_spec.rb:12:in `should full name is 'first_name last_name''

Finished in 0.103591 seconds

2 specifications, 1 failure
You have new mail.
[4250]%

二つ目のSpecが正しくないことがわかる。

簡単だが今日はここまで。
次回、RSpec on RailsとRSpecの中身を詳しくみていきたい。


参考
RSpec on Rails
RSpec
RSpec Documentation