まだ信者になっていない人に向けた RSpec の奨め
某書籍の執筆をちゃんとやろうと再開したのですが、こんなのでリーチしますかね?抜粋。
下にいくほど信仰が高まっていますが、いちおう現世利益を前面に出してみました。
校正前とはいえ元原稿の抜粋なので、レビュー&突っ込み(これは嬉しいの?とか)大歓迎です。むしろお願いします。あと6個書けると10の理由になって流行に乗れるのでぜひに。
標準でモック機構を備えている
まだ作成していないクラスの呼出側を設計する場合や、外部の認証サーバとの連携などテスト時には制御することの難しい機能開発する場合に、その難しい部分を簡単にモックすることができます。また、単にその機能があるように振る舞う(常にtrueを返す、など)ではなく、内部でどのメソッドが呼ばれるかもテスト時の検証対象にできるため、デベロッパーテストによる設計が行いやすくなります。
ビューやコントローラの単体テストを記述できる
Rails のファンクショナルテストでは、モデル・ビュー・コントローラのすべてを統合したテストを実施できます。これは、言い換えるとコントローラのみ、あるいはビューのみ、といった単体テストの記述が比較的難しいというデメリットも伴います。
RSpec はビューやコントローラを独立させた状態で記述できるため、「まずは画面項目を確定させたい」「ビューはできていないけれど、コントローラ内で行う処理を明確にしたい」といった場合にそれぞれを単体で記述できます。
出力フォーマットがわかりやすい
開発が進みテスト資産が溜ってくると、個々のテストで何を検証したか、ということを忘れてしまいがちです。また、テストの絶対数は少なくても複数のテストを実施する場合に、どの項目はパスし、どの項目は失敗したか、という情報を直感的に取得するのが難しくなります。
RSpec では標準で出力できるフォーマットが親切なものになっているため、上記を確認しやすくなっています。
例えば冒頭で示したサンプルを実行した場合、結果はこのように出力されます。
When the array is [:one, :two, :three], the array - should not be empty Finished in 0.000888 seconds 1 specification, 0 failures
もちろん、一気に実行するときには個々の項目を出力しないこともできます。
. Finished in 0.000663 seconds 1 specification, 0 failures
検査対象を動作するコードとして明示できる
test/unitで行うassertは「actualがexpectedと同じであることを検証する」といった形でコードに現われます。
assert_equal( expected, actual )
対してRSpecでは、「actualがexpectedと同じであること」をダイレクトに記述可能です。
expected.should eql(actual)
この差は小さなものに感じますが、筆者の場合、テストによる設計を行う場合には対象の状態そのものに関心がある場合がほとんどです。そういった場合に思考の回り道をすることなく記述できます。