2014-01-14 4 views
5

letの通常の動作は、基本的にサンプルブロック(つまり、ブロック)にバインドすることです。ほとんどの場合、これは問題ありませんが、大規模なオブジェクトを複数の例で使用されています。このような場合、インスタンス変数はテストスイートの健全性にとってほとんど必要になります。RSPEC Alternate Scopingを使用する

時間がかかるなどの化合物であろう。例の数はで呼び出さ例において

  • LET = *オブジェクトの作成時に呼び出さ#例
  • インスタンス=オブジェクトの作成時

を3を超えると、今回はすぐに問題になります。

ほとんどの場合、インスタンス変数を使用することは異端ですが、letの現在の状態では、あまりにも多くの研究をすることなく、あまりにも独創的なレイビングのように見えます。私がletをサポートするために読んだ記事のうち、唯一の議論は、怠惰なローディングとスコープの懸念に対するいくつかの魅力であり、どちらも書かれたテストでは無関係です。

レイジーローディングは、データが必要かどうかわからない場合にのみ有用なので、テストでは意味がないようです。そのような場合は、最初にそのテストのためにデータを作成するのに迷惑をかけるのはなぜですか?

テストでオブジェクトを変更していない場合(ヒント:スタブしないでください)、インスタンス変数は決して問題にはなりません。そうであれば、カップリングは変数の障害ではなく、テストそのものです。

TL; DR:let type文を代替ブロック領域にバインドする方法はありますか?理想的には、この問題を軽減するために記述ブロックとコンテキストブロックの両方にバインドしたいと思います。

例:local_bindはなく、それが実行される例よりも現在のブロックコンテキストにLETを結合する

describe 'Person' do 
    local_bind let(:person) { Person.new(actual_data) } 

    context 'It has no data' do 
    local_bind let(:person) { Person.new(blank_data) } 
    # tests 
    end 
end 

ました。言うまでもなく、これは推論構文ですが、ここでは一般的な考え方を示します。

これは、ブロック領域内にあるすべてのサンプルにわたって使用されるオブジェクトを宣言することを可能にします。これは、メモの例のみの悪影響を大幅に削減します。

これらの問題は、それはより高価なものに紛れ見えるようになります(50回の呼び出しが0.001インスタンス化はまだかなり速いです*)基本的なオブジェクトの目に見えマニフェストへの傾向があるものではありませんが(50回の呼び出しが0.1 = 5秒*。)

を私はこれまでにこれを取ってきたものを見てきましたが、何とかスペックヘルパーになってパフォーマンスの抽象度の低いところで使用されると、3500テストのテストスイートがどのように素早く膝に曲げられるかを想像することができます。これまでに観察された違いは、JSONの問題から8:15から1:57にかけての時間が75%短縮されたことです。これを行うと、20秒未満になると予測されました。これの証拠を得ることに取り組んでいます。

+1

あなたは理想的に何をしたいのかのコード例を提供できますか? – Eugene

+0

オブジェクトの作成時間を避けるインスタンス変数の表示方法を明確にすることはできますか? 'before(:all)'の使用について話していますか? –

+0

この場合、はい。前に:すべてはそれのための最も有望な候補者であろう。私はその意味とティアダウンが気に入らないが、この段階では最も実りあるようだ。上記のように、letステートメントは単一の例でしかキャッシュされません。つまり、呼び出されるすべてのサンプルのデータ全体をリロードします。テスト用の変数を変更しないと、インスタンス変数は、 。 – baweaver

答えて

-1

https://github.com/rspec/rspec-core/issues/1246

私はRSPECコアチームとこの正確な問題を議論してきた、と彼らはこの不幸な命名規則をクリアするつもりはありません。代わりに、彼らはプログラマーがそれほどよく分からず、手を持ち、後で取り上げなければならないと主張するようだ。作品の一部、そのロット...

関連する問題