8

我有一个升级到版本 3.2.11 的旧 Rails 应用程序,其中有很多使用 capybara 版本 1.0.1 编写并使用 selenium 驱动程序运行的请求规范。每次测试后,使用截断策略使用 database_cleaner 清理数据库。

我想使用 poltergeist 而不是 selenium,并将 capybara 从 1.0.1 升级到 1.1.4 以便能够使用最新版本的 poltergeist。仅更改 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 创建的死锁的另一端是什么。任何解决这个问题的想法都是最受欢迎的。

有人知道 capybara 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 内容的步骤(或在您的情况下为“规范”)的末尾。我想会发生什么是 cucumber/rspec 在 JS 驱动程序仍在等待 ajax 响应时调用数据库清理器。

于 2013-02-25T16:28:54.967 回答
1

我们使用的解决方案是在页面中找到应该更改以响应成功的 ajax 调用的内容。所以像:

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