PIYO - Tech & Life -

rspec-parameterizedで条件だけが異なるテストコードをDRYに書く

Ruby RSpec

テストのロジックは同じだけど、入力値とそれに対する結果が異なるみたいなテストをシンプルにかけるrspec-parametrizedというgemがあります。

GitHub - tomykaira/rspec-parameterized: RSpec::Parameterized supports simple parameterized test syntax in rspec.
RSpec::Parameterized supports simple parameterized test syntax in rspec. - GitHub - tomykaira/rspec-parameterized: RSpec::Parameterized supports simple parameterized test syntax in rspec.

存在は知ってたけどしばらく使ってなかったんですが、試しに入れてみたらすごくシンプルに使えるし、パラメータ変えてテストできるようなメソッドにしようみたいな意識がより働いてコードに良い影響もありそうな気がしています。

wherewith_themを使ってテストを書いていきます。↓はREADMEのサンプルの一部でして、whereに値の組み合わせ、with_themにテストコード自体を書く使い方をします。

describe "plus" do
  where(:a, :b, :answer) do
    [
      [1 , 2 , 3],
      [5 , 8 , 13],
      [0 , 0 , 0]
    ]
  end

  with_them do
    it "should do additions" do
      expect(a + b).to eq answer
    end
  end
end

↑の例だと、a,b,answerという3つのパラメータにセットする値をArrayのArrayで渡しています。すると、with_themに書いたテストが以下の3つの条件で実行されるというわけです。

  • a=1, b=2, answer=3
  • a=5, b=8, answer=13
  • a=0, b=0, answer=0

whereの書き方には↑のようなArrayのパターンやHashを使ったパターン、さらに独自のテーブル記法を使うこともできます。

using RSpec::Parameterized::TableSyntax

where(:a, :b, :answer) do
  1 | 2 | 3
  5 | 8 | 13
  0 | 0 | 0
end

直感的っちゃ直感的ですが、using RSpec::Parameterized::TableSyntaxしないと使えなくてひと手間かかるとも言えるので、この辺は好みですね。

ということで、パラメータのみが変わるテストはrspec-parameterizedでDRYにして、入出力の条件にフォーカスして必要なテストをかけるようにしましょー。