ruby on rails -将capybara从1.0.1升级到1.1.4使database_cleaner打破了我的



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

我想用poltergeist代替selenium,并将capybara从1.0.1升级到1.1.4,以便能够使用最新版本的poltergeist。仅更改capybara gem(及其依赖项)就会导致运行我的规范出现问题。

在每个spec之后的清理处理程序中,我总是从Postgresql数据库中得到死锁错误。

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来创建测试数据,除此之外没有什么特别的。

我还没能弄清楚是什么保持死锁的另一端是由database_cleaner创建的。欢迎提出任何解决这个问题的建议。

有谁知道在capybara 1.0.1和1.1.4之间有什么变化,可能已经开始导致这些问题?

我在黄瓜中放置

来解决这个问题
sleep 0.2

在步骤的末尾(或者在您的例子中是"spec"),它做一些AJAX的事情。我想发生的事情是,cucumber/rspec调用数据库清理器,而JS驱动程序仍在等待ajax响应。

修复不是使用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

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

click_on('Save')
expect(page).to have_content('Saved')

相关内容

  • 没有找到相关文章

最新更新