【Rails】RSpecで特定のテストケースだけbeforeをスキップする

RSpecでは、before do ... endを使うことで、各テストケースの前に共通して行う処理を記述できる。これを使ってテストデータを投入する処理などを書いておくと、テストケースが書きやすくなる。
しかし、例えばデータが1件もない状態での挙動をテストしたいときなど、一部のケースではbeforeをスキップしたいという場合もある。そのための直接の機能はRSpecにはないが、以下のようにすると実現させることができる。

describe 'test_case' do
  before do |example|
    unless example.metadata[:skip_before]
        ...
    end
  end

  context 'condition A' do
    it 'needs before procedure' do # beforeが実行される
      ...
    end

    it 'not need before procedure', :skip_before do # beforeがスキップされる
      ....
    end
  end

example.metadata は、任意のexample(=it)やexample group(=context)に対してつけられるメタデータ。これはRSpecの機能の一つであり、今回のケースだけでなく様々な用途に使える。
上の例では、2つ目のitに :skip_before という名前でメタデータを付与した(名前は何でもよい)。本来はハッシュに対応する値も付与するのだが、True/Falseでメタデータの存在確認をするだけなら値は必要ない。このようなメタデータの指定方法は、以下のドキュメントに記載されている。 relishapp.com

そしてbeforeを実行する際に、:skip_beforeというメタデータがあれば処理を抜けるようにすることで、特定のテストケースだけスキップさせることができる。もちろん、あまりにも多くのテストケースでスキップさせるようであればむしろbeforeを使うのをやめるべきだが、一部の特殊ケースをテストさせたい時には手軽な方法だろう。