8

バージョン 3.2.11 にアップグレードされた古い Rails アプリケーションがあります。このアプリケーションには、カピバラ バージョン 1.0.1 を使用して記述され、セレン ドライバーを使用して実行される多くの要求仕様があります。データベースは、切り捨て戦略を使用して database_cleaner を使用して各テストの後にクリーンアップされます。

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

各仕様の後、クリーンアップ ハンドラーで Postgresql データベースから一貫してデッドロック エラーが発生します。私の spec_helper はかなり基本的なもので、次のようになります。

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

私が得るエラーは次のようなものです:

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'

FactoryGirl を使用してテスト データを作成しますが、それ以外は特別な IMO はありません。

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

カピバラ 1.0.1 と 1.1.4 の間に変更があり、これらの問題を引き起こし始めた可能性があることを知っている人はいますか?

4

3 に答える 3

5

修正は、使用するのではなく、sleep予想されるものを待機するときに Capybara API メソッドのみを使用することです。

以下の 2 行目は失敗します (current_path待機していないため、3 行目は (has_selector?待機しているため) 動作します)。以下の Jonas Nicklas の記事へのリンクは、それをよく説明しています。

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

于 2013-06-05T22:10:45.083 に答える
5

配置することで、キュウリでこの問題を回避しました

sleep 0.2

いくつかのAJAX処理を行うステップ(またはあなたの場合は「仕様」)の最後に。JS ドライバーがまだ ajax 応答を待っている間に、cucumber/rspec がデータベース クリーナーを呼び出すとどうなるか想像できます。

于 2013-02-25T16:28:54.967 に答える
1

私たちが使用する解決策は、成功した ajax 呼び出しに応じて変更する必要があるページ内の何かを見つけることです。次のようなものです:

click_on('Save')
expect(page).to have_content('Saved')
于 2014-05-28T21:20:16.520 に答える