Railsのフィクスチャとその代替

レールに座っているのはそれほど昔ではありませんが、それでも既に何かを掘り下げています。 慎重に対処しなければならなかったトピックの1つは、レールテストでの器具とその代替品です。



フィクスチャ自体について少し

主題にあまり詳しくない人のための小さなレビュー。 Railsのフィクスチャは、テスト対象のオブジェクトで使用される事前に準備されたデータをテストデータベースに格納できるようにするものです。 テストコード自体では、 fixtures :users



メソッドを呼び出すだけで十分であり、Userクラスのオブジェクトのすべてのデータを自動的にロードします。 より詳細なレビューについては、 マニュアルを読んでください(ちなみに短い)。



開発者がフィクスチャを好まないのはなぜですか?

このツールは1つの問題を解決することで開発者を支援することを目的としていたにも関わらず、彼はいくつかの問題を作成しました。 ブログでよく表明される備品に関する主な不満は次のとおりです。

  1. フィクスチャは各テストに固有のものであることが意図されていますが、それでも各テストで使用可能です。 つまり、あるテストでユーザーオブジェクトのデータが必要な場合、別のテストでは既に多少異なっています。標準のフィクスチャではこれは不可能です。
  2. データベースのレコードが非常に少ない場合、フィクスチャがhas_one、has_many、habtm、has_manyなどのオブジェクトの関係をモデル化することははるかに困難になります:through-外部キーの正しい値を追跡する必要があります。 実際、標準的なメカニズムはそのようなhemoを避ける便利な方法を提供しますが(下記参照)、これはしばしば忘れられます。
  3. 最愛の人。 一部の開発者は、テストコードで直接使用されるデータを明確に見たいと考えています。


代替手段は何ですか?

フィクスチャの代替として、たとえば、 %w("Tom Bill Frank").each { |name| User.create(:first_name => name) }



など、テストで直接オブジェクトを主に作成できます%w("Tom Bill Frank").each { |name| User.create(:first_name => name) }



%w("Tom Bill Frank").each { |name| User.create(:first_name => name) }



。 私はこれをやろうとしましたが、ここでの欠点は、各テストの後に何らかの形で手動でテストベースをクリアする必要があることです。 フィクスチャがまだフィクスチャを使用するテストとともにこのようなテストが同時に起動されると、競合が発生する可能性があります-フィクスチャはトランザクションを使用してデータベースを充填/消去するため、偽のテストを実行する前に、データベースが実際にクリーニングされていないことが判明する可能性があります (たとえば、このため、単独で実行され、正常に合格しましたが、他のテストと一緒に実行されている非架空のテストはエラーをスローしました)。



コミュニティはさらに進んで、フィクスチャをバイパスするデータオブジェクトの作成を簡素化するいくつかのソリューション( 1、2 )を考え出しました。



ただし、フィクスチャを使用する方が便利なのはなぜですか?

モデルに新しいフィールドを追加し、その存在を検証することを想像してください。 ここで、オブジェクトを作成してデータを取り込む10の偽テストがあると想像してください。 これらの10個のテストすべてを編集するとき、あまり楽しいことはありません(ところで、問題は非常に重要です-これは、モデルにrestful_authenticationプラグインの構築を開始し、パスワードフィールドを追加したときに起こったことです)。 そのための単体テストと、何にも依存せず、モデルの機能をテストするためのデータのみを使用する単体テスト。



したがって、新しい問題を作成するソリューションに切り替えるよりも、フィクスチャ自体の中で記事の冒頭に示されている欠点を実際に解決する方が簡単です。 方法は次のとおりです。

  1. 各テストのフィクスチャ特異性の問題はFixtureScenariosプラグインによって解決されます。 各テストでは、 scenario :logging



    を指定するだけで十分scenario :logging



    とすべてのフィクスチャは、fixtures / loggingディレクトリからロードされます。 上記のリンクにより、記事には追加のFixtureScenarioBuilderプラグインが記載されています-私はそれを使用しようとしましたが、最初に、すべてのテストが失敗する原因となったバグがあり、次にあまり意味がありませんでした、なぜなら 3行のフィクスチャの束の動的な作成は、ERbを使用してYAMLファイルに直接整理できます(「ERbを使用したダイナミックフィクスチャ」マナセクションを参照)。
  2. 外部キーを使用して大量のレコードを追跡する方法の問題は 、フィクスチャによって提供される標準的な方法で解決されます



    ### in pirates.yml

    reginald:

    name: Reginald the Pirate

    monkey: george



    ### in monkeys.yml

    george:

    name: George the Monkey

    pirate: reginald







    この場合、レコードIDは明示的に設定されません(ところで、フィクスチャでこれを行う理由はまったくありません)が、自動的に割り当てられます。 レールは、georgeとreginaldを対応するIDに自動的に置き換えます。 そして今、関係has_oneとbelongs_toがあります。 このアプローチの使用に関する詳細は、 マニュアルの 「高度なYAMLフィクスチャ」セクションに再度記載されています 。 特に強力なこのアプローチは、ERbを使用したレコードの生成と組み合わせて使用​​できます。

  3. 私の意見では、 可視性の問題もFixtureScenariosプラグインを使用して解決されます。 名前付きスクリプトを使用すると、どのスクリプトをテストで使用するかを制御するだけで、このスクリプトにどのデータがロードされ、将来この問題に戻らないかを一度考えることができます。 必要に応じて、新しいスクリプトを追加できます。このスクリプトは、ネストすることができます(たとえば、フィクスチャ/ロギングのデータが最初にロードされ、次にフィクスチャ/ロギング/ adminからロードされます)。


専門家のコメント、追加、意見に感謝します。



All Articles