RSpecのここがすごい!

RSpec?


Rubyには、Test::Unitがあるし、普通にUnitTestが書けるよね?なんで??

まずはこれを見てくれ


require 'lru_cache'
 
describe LruCache do
  describe "を初期化する場合" do
    it "は、サイズを渡したら、そのサイズのキャッシュができる." do
      targ = LruCache.new(10)
      targ.limit.should == 10
    end

    it "もし、サイズにマイナス値を渡したら、例外が発生する." do
      lambda{ LruCache.new(-1) }.should raise_error(ArgumentError)
    end

    it "もし、サイズにnilを渡したら、例外が発生する." do
      lambda{ LruCache.new(nil) }.should raise_error(ArgumentError)
    end

    it "もし、サイズに数値以外を渡したら、例外が発生する." do
      lambda{ LruCache.new("a") }.should raise_error(ArgumentError)
    end
  end
end

  1. まず LruCacheに関する記述(describe)だよ、と宣言して
    1. そのうちの「初期化をする場合」のテストだよ、と宣言して
      1. 「サイズを渡したら、そのサイズのキャッシュができる」べきだと、通常できることを説明していて
        1. その内容でtarg.limitは10であるべき(should)と明示して
      2. 「サイズにマイナス値を渡したら、例外が発生する」べきだと、引数がおかしい場合に起こることを説明していて
        1. その内容でArgumentErrorというerrorが発生するべきと明示して
      3. 「サイズにnilを渡したら、例外が発生する」べきだと、引数がおかしい場合に起こることを説明していて
        1. その内容でArgumentErrorというerrorが発生するべきと明示して
      4. 「サイズに数値以外を渡したら、例外が発生する」べきだと、引数がおかしい場合に起こることを説明していて
        1. その内容でArgumentErrorというerrorが発生するべきと明示して

これを見るだけで、LruCacheが「何をするプログラムなのか」が見えてくる!
しかも、Test::Unit(JavaのJUnit4.1以前相当)よりも、より記述が簡便で読みやすい!

UnitTestの次の流れ-より人が読みやすいテストへ


UnitTestが広まるなかで、認識されていったこと

  1. UnitTestは、ホワイトボックス・テスト(テスト対象の全コードを理解したうえでのテスト)ではない。
  2. UnitTestでテストしているのは、テスト対象のクラスとメソッドのインタフェースだ。
    1. つまりは、ブラックボックス・テスト、ステートボックス・テストに他ならない。
  3. インタフェースの肝とは、インプットとアウトプットが何であるかをしっかり確立すること。
    1. つまりは、そのインタフェースの振る舞いをしっかり確立すること。

そうだ!振る舞いをテストするんだ!!

-> Behavior Test という認識へ。

だったら、振る舞いをもっとわかりやすく記述できないかな?

-> Java の場合 : JUnit4.5 assertThat() の登場
-> Ruby の場合 : RSpec の登場

いずれでも、根底にある思想は「コードは徹頭徹尾人が読むためにある存在」だということ。


最終更新:2010年01月24日 15:09