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

问题描述 投票:0回答:2

我们一直在经历一个间歇性的问题,我想看看这里的人是否有洞察我们如何解决它。我们正在与Minitest + Capybara和Chrome无头驱动器进行集成测试。

当测试完成并且数据库获得ROLLBACK时,会出现问题。仍然有一些未完成的请求在后台运行,如果他们试图访问不可用的数据库信息,可能会发生崩溃(如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错误而崩溃。

  • 打开弹出窗口时,会向DOM添加<img src='/files/123' />。然后浏览器查询并重定向到ActiveRecord表示URL。
  • 集成测试非常简单,并且验证是否存在某个类,然后测试结束并且数据库是ROLLBACK。
  • /files/123的请求仍在运行,然后尝试加载不再存在的blob(数据库记录),并导致意外的测试失败。

有没有人遇到过这样的问题,如果有的话,你是如何设法避免它的?

我们使用Ruby 2.5.0,Rails 5.2.2,Capybara 3.0.3

谢谢

ruby-on-rails ruby capybara minitest
2个回答
1
投票

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


0
投票

原来我们用这种方式实现了Capybara:

def after_teardown
  super
  Capybara.reset_sessions!
  Capybara.use_default_driver
end

但是Rails在superafter_teardown调用中回滚数据库。因此,在Capybara等待会话结束之前,数据库已经回滚。

super之后移动Capybara.reset_sessions!做了伎俩(将其放入def teardown也是有意义的,这很可能是我们将要做的)。

感谢@ThomasWalpole指出我正确的方向。

© www.soinside.com 2019 - 2024. All rights reserved.