RSpecの violated と pending

RSpecにはテストの実装が不完全であることを表すための二つのメソッドがある。

violated(message = nil) テストを強制的に失敗させる
pending(message) テストが意図的に保留状態であることを示す

violated

Test::Unitにおけるflunkと同じようなもの。

it のブロック内に内に書くとそのテストケース(Example)は必ず失敗する。

it "昨日布団の中で思いついた仕様" do
  violated
end

さっさとテスト書けよというプレッシャーが漂う。

pending

テスト自体や実コードの実装の保留状態を示す。

it のブロック内にpendingと書くと、その行以降の処理は実行されない。
pendingメソッドを使うときには引数に必ず理由を書かなくてはならない。

it "一昨日風呂の中で思いついた仕様" do
  pending("やんごとなき理由")
  # 検証されないエクスペクテーション
end

またpendingにはブロックを与えることができ、その場合はそのブロック内の処理だけがペンディング扱いになる。

it "こないだバイクに乗ってて思いついた仕様" do
  pending("大人の事情") do
    # 実コード未実装のため例外が出るエクスペクテーション
  end
end

こちらはpendingブロック内のエクスペクテーションがすべてパスすると逆にテスト失敗とみなすようになる。
pendingなのに通るのはおかしいと言うことだろう。

未実装によるpending

it にブロックを与えなかった場合には自動的にpendingになる。

it "先日散歩してて思いついた仕様"

仕様だけ先にぱぱっと書いてしまうとpendingの多い状態になるだろう。
しかし強制的に全部失敗と言われるよりは気楽に仕様をどんどん書いて行けそうだ。

使い分け

violatedとpendingの使い分けの一般的なポリシーがいまいちわからない。

これだけはどうしても今日中に実装しなくてはならない!といか言うときだけviolated使えばいいかんじかな。例えば緊急度の高いバグ対応用のテストとか。
あとはpendingにしといて粛々と実装。

まあとりあえず最低限チーム内でどういう扱い方をするか合意がとれていればよさそうだ。

「保留」の意味合い

最終的にはpendingもゼロを目指すのがやっぱり本筋なんだろうな。
「状況が変わらない限りずっとペンディングの機能」とかは多分ペンディングのレベルが違うのでいったんテストごと削ってしまうのがクリーンな気がする。

「テストの保留」および「近く対応すると決まっている実装の保留」であって「機能を実装するかしないかわからないから保留」とは違うと区別していた方が幸せになれそうだ。
やっぱり全部グリーンにならないと気持ちよくないもんな。

参考

Rubyist Magazine – スはスペックのス 【第 1 回】 RSpec の概要と、RSpec on Rails (モデル編)

次の記事

RailsでAmazon Webサービス