2013-01-10 5 views
8

古いRailsアプリケーションをバージョン3.2.11にアップグレードしました。これは、capybaraバージョン1.0.1を使用して作成されたリクエスト仕様が多く、セレンドライバ。データベースは、切り捨て戦略を使用してdatabase_cleanerを使用して、各テスト後にクリーンアップされます。capybaraを1.0.1から1.1.4にアップグレードすると、database_cleanerが仕様を破る

最新バージョンのポルターガイストを使用できるようにするには、セレンの代わりにポルターガイストを使用し、カピバラを1.0.1から1.1.4にアップグレードします。カピバラの宝石(およびその依存関係)を変更するだけで、仕様の実行に問題が生じました。

Postgresqlデータベースのデッドロックエラーは、各仕様の後にクリーンアップハンドラで一貫して取得できます。私spec_helperはかなり基本的であり、このようになります:私は、テストデータを作成していないが、それ以外IMO特別なことは何もしFactoryGirlを使用

An error occurred in an after hook 
    ActiveRecord::StatementInvalid: PG::Error: ERROR: deadlock detected 
DETAIL: Process 41747 waits for AccessExclusiveLock on relation 17612 of database 16396; blocked by process 41752. 
Process 41752 waits for RowExclusiveLock on relation 17529 of database 16396; blocked by process 41747. 
HINT: See server log for query details. 
: ALTER TABLE "aaa" ENABLE TRIGGER ALL;ALTER TABLE "bbbb" ENABLE TRIGGER ALL;ALTER TABLE "ccc" ENABLE TRIGGER ALL; 
    occurred at /xxx/.bundle/gems/activerecord-3.2.11/lib/active_record/connection_adapters/postgresql_adapter.rb:652:in `async_exec' 

RSpec.configure do |config| 
    config.mock_with :rspec 

    config.use_transactional_fixtures = false 

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

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

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

私が手にエラーがこのようなものです。

私は、database_cleanerによって作成されたデッドロックのもう一方の端を保持しているものを把握できませんでした。それを理解するためのアイディアは大歓迎です。

capybara 1.0.1と1.1.4の間の変更があり、変更されている可能性があります。これらの問題が発生している可能性がありますか?いくつかのAJAXのものをして、私は(またはあなたのケースでは「スペック」)ステップの終わりに

sleep 0.2 

を配置することによって、キュウリでこの問題を回避するだ

+0

私は実際の体験反対側に譲ってください。 1.1.2からcapybara 1.1.4にアップグレードするまで、テストで間欠的にデッドロックが発生しました。申し訳ありませんが、私のコメントは役に立たない。 =/ –

+0

私はデッドロックの問題を経験している唯一の人ではないことを嬉しく思っています:-)同時に2つのスレッドがなぜ同時にテーブルにアクセスしているのか分かりません。 DatabaseCleanは、実際のテストが完了した後にのみ動作するはずです... – HakonB

+0

ああ、これは愚かな質問かもしれませんが、DatabaseCleaner gemを更新しようとしましたか?また、FWIW私たちはdelayed_jobの使用を開始した後にのみエラーが発生したと思っています。 –

答えて

5

。私は、JSドライバーがまだajaxレスポンスを待っている間、キュウリ/ rspecがデータベースクリーナーを呼び出すということが起こると思います。

+0

私のために働きました。これに遭遇している人が増えているのは不思議そうです。 –

+0

私のために働いた。実際の解決策はありますか? – morgler

+0

これは動作しますが、不必要にテストが遅くなり、失敗することがあります。この修正は、テスト終了時にCapybara API(has_content?など)を呼び出すことです。私は以下の答えで詳しく述べました。 –

5

修正プログラムはsleepを使用するのではなく、期待されるものを待つためにCapybara APIメソッドのみを使用します。

以下

、2行目は失敗します(current_pathが非待機ですが、ライン3作品(has_selector?待ちなど)。ジョナスニクラス記事へのリンクは以下のそれをよく説明しているよう。

click_on 'signup_button' # Which does an AJAX redirect to /dashboard 
assert_equal dashboard_path, current_path # This causes the deadlock error as Capybara doesn't wait. 
assert page.has_selector?("#dashboard") # This works as it causes Capybara to wait for the new page. 

http://www.elabs.se/blog/53-why-wait_until-was-removed-from-capybara

+0

私はこれがCapybara 2でのみ動作することを確信しています。あなたはCapybara <2でそれを試しましたか? –

1
我々が使用

ソリューションは、成功したAJAX呼び出しに応じて変更する必要がありますページで何かを見つけることですのようなものだから、:。

click_on('Save') 
expect(page).to have_content('Saved') 
関連する問題