2011-07-05 20 views
5

我正在使用Ruby on Rails 3並編寫測試,但速度太慢。 有沒有一些好的配置或工具可以讓它更快?如何更快地在RoR上運行測試?

+3

如果您使用RSpec的,你可以用[叉勺(http://rubygems.org/引導寶石/ spork) –

回答

2

正如@eml所說,如果您使用RSpec,則可以使用Spork。這基本上會啓動環境(這是緩慢的部分),然後保持它周圍,每次運行規格時分叉。

對於「環境始終加載」問題的更一般解決方案,可以安裝rails-sh並在shell中運行測試。

附註:Ruby 1.9.3應該稍微緩解這個問題,因爲需求時間已經被優化。

4

也許最大的速度增益來自小心不要撞到數據庫,除非你需要。模擬對象而不是從數據庫中獲取它們,和/或(如果您使用的是工廠女孩),儘可能使用Factory.build(:stuff)而不是Factory(:stuff)。只有當你這樣做,你應該開始嘗試進一步優化與spork

更新: 個人而言,我也開始認爲你不應該掛起你的測試速度無論如何。速度更快顯然會更好,但隨着應用程序的增長,測試套件將會增長,但無論如何,它會最終變得比您想要的慢。我越來越依賴測試更改代碼並在後臺工作的autotest gem(guard-rspec做類似的工作)。當您的應用程序達到1000次測試時,您無需等待整個套件完成每次更改,但測試運行的速度很快。

+0

偉大的建議。我真的很感激代碼,你可以告訴開發人員在這方面的照顧。我唯一的警告,我不一定會堅持快速測試作爲Spork的必備條件。特別是在經常執行一小部分選擇規格時,加載軌道環境可能是一個真正的阻抗。 –

+0

公平的觀點 - 我猜這是對於課程的馬匹 - 我對其他答案之一作出了反應,似乎表明spork是某種銀彈......我不認爲這是作者的意圖,但我認爲這有點誤導 – chrispanda

2

恕我直言,減速測試的主要部分是燈具的默認配置。如果你的配置是(在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 

則數據庫爲每個測試文件重新只有一次,而你只加載你真的需要在每個測試方法的記錄。

這取決於測試數據集的大小,無論您發現測試數據庫創建的時間都可以接受。當我有一些相當大的測試數據時,我只在整個測試套件之前加載了一次燈具,但該項目是在Rails 1中的,而且我對它進行了大量修改,所以我不知道該怎麼做在Rails 3中(至少在某個新項目中問題開始變得痛苦的時候)。

測試是否應該擊中數據庫還有一場無休止的討論。如果你認爲他們應該(因爲數據庫合作也應該被測試),那麼你可以檢查設置這些參數是否有助於你(或任何讀這些答案的人)。

0

嘗試開發,以便可以在不需要加載整個Rails應用程序框架的情況下執行大部分測試。在你的天賦的幫手,跳過加載環境或RPEC /導軌如果只有快速測試正在執行,類似...

# /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 

爲了紀念測試「快」,在, :fast => true選項添加到其it通話或撥打周圍的電話describe

要僅運行快速測試,請從命令行界面執行rspec --tag fast

可能很難弄清楚如何構建代碼,以便測試可以從Rails中單獨運行(當然,您仍然希望具有不能單獨運行的功能和集成測試)。

我的兵工廠中的一個訣竅是避免直接在ActiveRecord模型或其他類上編寫代碼,而寧願將它寫在mixin模塊上。你可以通過定義主題是由該模塊擴展對象測試的mixin模塊...

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

    it 'does something' do 
    # ... 
    end 
end