2011-07-05 3 views

答えて

2

@emlによれば、RSpecを使用している場合、Sporkを使用できます。これは、基本的には、(遅い部分です)環境を起動し、あなたの仕様を実行するたびにフォークする、それを保持します。

"環境が常にロードされる"問題のより一般的な解決策は、rails-shをインストールし、シェル内からテストを実行することができます。

サイドノート:Ruby 1.9.3では、必要な時間が最適化されているため、この問題はわずかに緩和されます。

4

おそらく最大のスピードを得るためには、必要がない限りデータベースにヒットしないように注意する必要があります。データベースからフェッチするのではなく、モックオブジェクトをモックするのではなく、ファクトリーガールを使用している場合はFactory(:stuff)の代わりにFactory.build(:stuff)を使用します。あなたがそれをしたときだけ、さらにスポークでさらに最適化しようとすると始めるべきです

更新: 個人的に、私はあなたのテストのスピードについてどうにかして諦めるべきではないと考え始めています。明らかに速いですが、アプリケーションが成長するにつれて、テストスイートは成長しますが、最終的にはあなたが望むよりも遅くなることに注意してください。私は、コードの変更をテストし、バックグラウンドで動作する自動テストの宝石にますます頼るようになります(guard-rspecは同様の仕事をします)。あなたのアプリが1000回のテストに達するまでに、あなたが変更を行うたびにスイート全体が完了するのを待っていなくても、テストは速く実行されます。

+0

大きなアドバイス。私は開発者がこの分野で世話をしたことを伝えることができるコードを本当に感謝しています。私の唯一の警告は、私は必ずしもスピークのための必要条件として高速テストを主張しないでしょう。特に、小さな仕様のセレクト仕様を頻繁に実行する場合、レール環境をロードすることが本当のインピーダンスになる可能性があります。 –

+0

公正なポイント - 私はそれがコースの馬だと思います - 私はスポークが何らかの銀の弾丸であることを示唆していたと思われる他の回答の1つに反応していました...私はこれが作家の意図したものではないと思いますそれは少し誤解していたと思った – chrispanda

2

IMHOテストの主な減速部分は、フィクスチャのデフォルト設定です。ご使用の構成で(test/test_helper.rb中)の場合:テスト用データベースが古いデータから洗浄される各テスト方法は、すべてのテーブルが読み込まれる前に

class ActiveSupport::TestCase 
    self.use_transactional_fixtures = false 
    self.pre_loaded_fixtures = false 
    self.use_instantiated_fixtures = true 

、その後、すべてのレコードがメモリに読み込まれます。

あなたが反対に設定を変更した場合:

class ActiveSupport::TestCase 
    self.use_transactional_fixtures = true 
    self.pre_loaded_fixtures = true 
    self.use_instantiated_fixtures = false 

は、データベースは、それぞれのテストファイルに対して一度だけ再作成され、そしてあなたが本当にそれぞれの試験方法で必要なレコードのみをロードします。

テストデータベースの作成に時間がかかるかどうかは、テストデータセットのサイズによって異なります。いくつかかなりのテストデータがあると、テストスイート全体の前に1回だけフィクスチャをロードしましたが、そのプロジェクトはRails 1であり、大幅に変更されていますRails 3で(少なくとも新しいプロジェクトでは問題が始まるまで)。

テストがデータベースにヒットするかどうかについての議論はありません。 (データベースの協力もテストしなければならないので)これらのパラメータを設定するだけであなた(またはこれらの回答を読んでいる人)に役立つかどうかを確認できます。

0

ほとんどのテストをRailsアプリケーションフレームワーク全体をロードする必要なく実行できるように開発してください。あなたのスペックヘルパーでは、

# /spec/spec_helper.rb 
if RSpec.configuration.inclusion_filter[:fast] 
    # Setup required for fast tests in particular (if any) 
    # ... 
else 
    ENV["RAILS_ENV"] ||= 'test' 
    require File.expand_path("../../config/environment", __FILE__) 
    require 'rspec/rails' 

    Dir[Rails.root.join("spec/support/**/*.rb")].each {|f| require f} 
end 

RSpec.configure do |config| 
    # ... 

    unless RSpec.configuration.inclusion_filter[:fast] 
    # If you're not using ActiveRecord, or you'd prefer not to run each of your 
    # examples within a transaction, remove the following line or assign false 
    # instead of true. 
    config.use_transactional_fixtures = true 
    end 
end 

は「速い」などのテストをマークするには... /レールのみの高速テストが実行されている場合は、何かのような環境やrpecをロード飛ばし、その itコールに , :fast => trueオプションを追加または周囲の describeコールに送信します。

高速テストのみを実行するには、コマンドシェルからrspec --tag fastを実行します。

コードをどのように構造化してテストをRailsとは別に実行できるかを理解するのは難しいかもしれません(もちろん、別々に実行されない機能テストと統合テストが必要です)。

私の兵器の一つのトリックは、ActiveRecordモデルや他のクラスに直接コードを書くことを避け、代わりにmixinモジュールに書くことです。あなたはRSpecのを使用している場合は、[先割れスプーン](http://rubygems.org/をブートストラップすることができます...そのモジュールによって拡張されたオブジェクトであることが件名定義することにより、

describe 'MyModule', :fast => true 
    subject{ Object.new.tap{|o| o.extend MyModule} } 

    it 'does something' do 
    # ... 
    end 
end 
関連する問題