如何避免在集成测试中数据库回滚后挂起的请求失败?

How to avoid pending requests to fail after database rollback in integration tests?

我们一直遇到间歇性问题,我想看看这里是否有人知道我们如何解决它。 我们正在使用 Minitest + Capybara 和 Chrome 无头驱动程序进行集成测试。

问题发生在测试完成并且数据库被回滚时。后台可能仍有一些未完成的请求 运行,如果它们尝试访问不可用的数据库信息,则可能会发生崩溃(如 RecordNotFound)。

这种问题最常发生是因为 AJAX 请求,为此,我们已经在使用 wait_for_ajax 助手(我们开发的我们自己)等到浏览器完成他的请求。

未解决的问题出现在 <img> HTML 标签中,因为即使测试已完成,浏览器仍会尝试异步加载图像。

这是一个几乎总是会导致问题的代码示例:

test 'image popup should contain some class' do
  upload_some_images # Uploads images
  visit '/list_of_images' # Some page with list of images, you can click on the image and it opens it in a popup

  find('.image-popup-open-button').click # Open image in a popup window
  assert_selector '.some-class-must-be-present'
end

这是一个简单的测试,但在我们的案例中它总是会崩溃并出现 ActiveRecord::RecordNotFound blob id=xxx 错误。

有没有人遇到过这样的问题,如果遇到过,你是怎么避免的?

我们正在使用 Ruby 2.5.0,Rails 5.2.2,水豚 3.0.3

谢谢

原来我们是这样实现 Capybara 的:

def after_teardown
  super
  Capybara.reset_sessions!
  Capybara.use_default_driver
end

但是 Rails 在 after_teardownsuper 调用中回滚了数据库。因此在 Capybara 等待会话完成之前数据库已回滚。

Capybara.reset_sessions! 之后移动 super 达到了目的(将它放在 def teardown 中也是有意义的,这很可能是我们要做的)。

感谢@ThomasWalpole 为我指明了正确的方向。

假设 Capybara 正在管理正在测试的应用程序的 运行,Capybara.reset_sessions! 将等待所有打开的请求完成。这需要在数据库回滚之前发生。如果使用 Rails 系统测试,这将在 teardown 块中处理,只要您从您定义的任何 teardown 块中调用 super。如果不使用系统测试并且只是将测试基于 IntegerationTests,则需要定义一个调用 Capybara.reset_sessions!teardown 块,以便在 Rails 回滚之前等待所有请求完成数据库。