1

我有一個功能/集成規範貫穿整個用戶流程。在用戶流程結束時,應用程序中的頁面將顯示Postgres數據庫中的一些記錄。當我自己運行測試時,它會通過。我可以看到它通過各種步驟正確保存,因爲硒驅動程序打開Firefox:Capybara.current_driver = :selenium。然而,當它在一堆控制器規格之後運行時,這個規範幾乎可以預料地失敗。在這些控制器的規格,我做的唯一有趣的是運行此登錄功能:使用DatabaseCleaner和事務進行快速測試。如何調試?

module DeviseMacros 
    def login_user 
    before(:each) do 
     @request.env['devise.mapping'] = Devise.mappings[:user] 
     user = create(:user_with_active_account) 
     sign_in user 
    end 
    end 
end 

所以我這樣稱呼它:

describe AwesomeController do 
    login_user 

    it 'responds with 200' do 
    get :new 
    expect(response.status).to eq 200 
    end 
end 

當控制器規範運行後我立刻就可以知道測試將失敗,因爲某些UI元素應該顯示取決於數據庫中的內容,顯然它們不存在。

我DatabaseCleaner策略如下:

RSpec.configure do |config| 
    config.before(:suite) do 
    DatabaseCleaner.clean_with(:truncation) 
    end 

    config.before(:each) do 
    DatabaseCleaner.strategy = :transaction 
    end 

    config.before(:each, js: true) do 
    DatabaseCleaner.strategy = :truncation 
    end 

    config.before(:each) do 
    DatabaseCleaner.start 
    end 

    config.after(:each) do 
    DatabaseCleaner.clean 
    end 
end 

經過反覆試驗,我改變

config.before(:each) do 
    DatabaseCleaner.strategy = :transaction 
    end 

config.before(:each) do 
    DatabaseCleaner.strategy = :truncation 
    end 

而且沃拉,它傳遞。當然現在測試套件要花費兩倍的時間。

我已經爲了保證:truncation用於標記他們我所有的:selenium測試與js: true但其實並不重要,因爲:selenium已經推動這些。但是,最重要的是,這些功能規格在這些控制器規格之後仍然失敗。

我應該在哪裏找?我如何繼續調試?

唯一的其他獨特的東西我在這裏可能涉及的是:

# In spec/support/shared_db_connection.rb 
# https://gist.github.com/josevalim/470808 
class ActiveRecord::Base 
    mattr_accessor :shared_connection 
    @@shared_connection = nil 

    def self.connection 
    @@shared_connection || retrieve_connection 
    end 
end 

# Forces all threads to share the same connection. This works on 
# Capybara because it starts the web server in a thread. 
ActiveRecord::Base.shared_connection = ActiveRecord::Base.connection 

如何調試進行的任何意見或想法,將不勝感激。

如果您有任何其他問題,請詢問。謝謝

更新:2016年6月1日

的導致失敗的準確代碼行是:

module DeviseMacros 
    def login_user 
    before(:each) do 
     @request.env['devise.mapping'] = Devise.mappings[:user] 
     user = create(:user_with_active_account) 
     sign_in user # <----- THIS GUY RIGHT HERE! When removed, the ControllerSpec fails but the integration test passes. 
    end 
    end 
end 

所以,出於某種原因,似乎擊中DB與此控制器規範(使用:transaction策略)會影響功能規範(使用:truncation策略)。

我在辯論控制器規格時根本沒有觸及數據庫,當試圖認證一個設計用戶,這對我來說很酷,但我覺得它不應該是那樣的。如果我確實希望能夠使用sign_in方法,有關如何繼續的任何想法?

謝謝

+0

BTW,會發生什麼時你到處使用「交易」策略?因爲我認爲這就是ActiveRecord補丁的意義所在,不是嗎? – BoraMa

+0

@BoraMa感謝您的建議。當在任何地方使用':transaction'時,我會得到更多的錯誤,這些錯誤似乎與數據庫相關。我更新了有關導致上述問題的代碼行的更多信息。有任何想法嗎? –

+0

好吧,我也會投票傾銷這個AR補丁,並嘗試在沒有它的情況下解決問題。你可以發佈你的'sign_in'方法嗎?順便說一句,我依稀記得我們在過去的測試中遇到過類似的問題。我們最終將測試分解爲兩個測試套件:所有非JS和所有JS,並且我們分別運行兩個測試套件,而沒有任何其他問題。 – BoraMa

回答

0

刪除共享連接黑客,因爲它會導致更多的問題比它的價值,並更新數據庫清理配置來推薦一個從數據庫清理自述 - https://github.com/DatabaseCleaner/database_cleaner#rspec-with-capybara-example

+0

我刪除了shared_connection代碼,並將database_cleaner規則更新爲與鏈接完全相同。錯誤仍然發生。然而,我確實發現了導致錯誤的確切代碼行,並更新了我上面的問題。這是否給你更多的想法? –

+0

解決方案需要檢查所有功能規格並使用標籤(:js)明確標記它們以確保它們全部使用「事務」。原來這些錯誤是從所有功能規格中隨機發布的。只需咬一口子彈就可以使用較慢的功能規格。 –