Techioz Blog

Rubocop 25 行ブロック サイズと RSpec テスト

概要

典型的な RSpec 単体テストでは、コードを構造化するためにネストされた Ruby ブロックを広範囲に使用し、DSL の「マジック」を利用して仕様を BDD ステートメントのように読み取らせます。

describe Foo do
  context "with a bar" do
    before :each do
      subject { Foo.new().add_bar }
    end

    it "looks like a baz" do
      expect # etc

理想的な仕様では、各例は比較的短く正確なものにすることができます。ただし、外側のブロックが 100 行以上になるのが通常のようです。これは、RSpec 構造がこのように機能し、ブロックを説明するために、それぞれに数行の特定の設定が含まれる可能性のある多くの仕様例を必要としないためです。説明されている主題のコードと同じサイズまたはそれより大きいサイズ。

Rubocop の最近のアップグレードにより、ブロックは 25 行を超えてはいけないという新しいルールが適用されました。 Ruby スタイルガイドには記載されていないので、その根拠はわかりません。それがなぜ良いことであり、デフォルトのルールセットに追加されるのか理解できます。ただし、アップグレード後、Rubocop テストは、tests/component_spec.rb:151:3: C: Block has too many rows のようなメッセージが表示されて何度も失敗します。 [68/25]

Rubocop などのコード メトリック ツールを使用する場合、私は「デフォルトを使用し、スタイル ガイドにリンクし、仕事は完了する」というポリシーを持ちたいと考えています。 (主に、タブかスペースかその他の細かい点について議論するのは時間の無駄であり、IME は決して解決されないからです) ここでそれは明らかに不可能です。当社の 2 つのコア データ品質ツールは、コード レイアウトのアプローチについて意見が一致していません。または、少なくともそれが私が結果を解釈する方法です。 , 仕様の書き方に本質的に間違った点は見当たりません。

それに応じて、Rubocop のブロック サイズ ルールを高いしきい値に設定しました。しかし、それは私に疑問を抱かせます - 私には何が欠けているのでしょうか? RSpec はコード レイアウトに現在では信用されていないアプローチを使用しているのでしょうか?また、RSpec テストでブロック サイズを削減するにはどのような合理的なオプションが必要ですか?大きなブロックを避けるためにコードを再構築する方法はわかりますが、それらは例外なく純粋に Rubocop のルールを満たすことを目的とした醜いハックです。すべてのブロックをヘルパー関数に分割します。

def looks_like_a_baz
  it "looks like a baz" do
         expect # etc
  end
end

def bar_context
  context "with a bar" do
    before :each do
      subject { Foo.new().add_bar }
    end
    looks_like_a_baz
  end
end


describe Foo do
  bar_context
  # etc

。 。 。つまり、それは実行可能ですが、この方法で大量の仕様例をヘルパー関数に変換することは、RSpec の設計で奨励されている読みやすいアプローチとは逆であるように思えます。

無視する方法を見つける以外に何かできることはありますか?

このトピックに関して私がここで見つけた最も近い既存の質問は RSpec & Rubocop / Ruby Style Guide で、これはテスト テンプレートを編集することで解決できるようでした。

解決策

通常、特定のブロックが長すぎる場合は、ファイルではなくブロックを指定します。

Metrics/BlockLength:
  AllowedMethods: ['describe', 'context']