RSpec を実案件で使ってみた

昨年末から、ある小規模(60画面程度)のRuby on Railsを使ったシステムを開発する際に、RSpecを使ってみましたので、その感想などを

screenshot

どこまで書くか

今回は、Model, Library, Helper に対してのRSpecのみ書きました、従来のRailsのUnitTestに相当する部分のみです。
ただし、コントローラーには絶対にロジックを書かないようにし、ロジックは Model, Library に書くようにしましたのでかなりテストは出来ていると思います。

読みやすい

RSpecは従来のユニットテストに比べコンパクトに書けるのでテストが読みやすくなります。理由はいろいろとあると思いますが

UniTestのassertは

  assert(期待値, テスト対象のメソッド)

とテスト対象が後ろの方にありますが、 RSpec では

テスト対象のメソッド.should == 期待値

なので、テスト対象が最初に現れパッとみて何のテスト(スペック)なのかが分かり易いです。

また、「テスト対象のメソッド.should == 期待値」という記述なのでメソッドの結果の一部を取り出したりなどの部分をイテレターのメソッドチェインで続けて書くのが自然で短く書けます。

sites(:shibuya).attr_values.map{|e| e.value}.sort.should == ["中規模", "渋谷区"]

もちろん、 describe や it に スペック (≒テスト内容)を書くのでテスト内容が解りやすくなります。

spec_server

スペックサーバーを使うと、Railsのライブラリーが読み込まれた状態でテストだけ実行され、高速にテストが実行でき気軽にテストが実行できるのが素晴らしいです。

モック

現在の時間を記録しておくアプリは多いと思います。しかしテストする際には現在の時刻はたえず変わるので不便です。もちろんRubyオープンクラスなので Time.now メソッドを書き換えてしまう事が可能ですが、そのようにコードを書くのも面倒です。

そこでRSpecのスタブ・モック機能が便利です、以下のようなスタブを書くことで Time.now はテスト中は 2008/12/3 15:00:00 を戻す事になるので 期待値に日時を書くことができます。

      time_now = Time.local(2008,12,3,15,0,0)
      Time.stub!(:now).and_return(time_now)

不思議なバグに出会う

今回RSpecを使っていて、ActiveRecord の before_save が何回も呼び出されているような動作をする事がありました。ただし、spec_server を使った場合のみでした。

この問題は RSpec 1.1.12 にバージョンアップして直りました。



結論として、RSpec は素晴らしです。今後もテストにはRSpecを使って行きたいと思います。