我们一直在经历一个间歇性的问题,我想看看这里的人是否有洞察我们如何解决它。我们正在与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
错误而崩溃。
<img src='/files/123' />
。然后浏览器查询并重定向到ActiveRecord表示URL。/files/123
的请求仍在运行,然后尝试加载不再存在的blob(数据库记录),并导致意外的测试失败。有没有人遇到过这样的问题,如果有的话,你是如何设法避免它的?
我们使用Ruby 2.5.0,Rails 5.2.2,Capybara 3.0.3
谢谢
假设Capybara正在管理正在测试的应用程序的运行,Capybara.reset_sessions!
将等待所有打开的请求完成。这需要在数据库回滚之前发生。如果使用Rails系统测试,只要从已定义的任何teardown
块调用super
,就会在teardown
块中处理。如果不使用系统测试并且只是将测试基于IntegerationTests,则需要定义一个调用teardown
的Capybara.reset_sessions!
块,以便在Rails回滚数据库之前让它等待所有请求完成。
原来我们用这种方式实现了Capybara:
def after_teardown
super
Capybara.reset_sessions!
Capybara.use_default_driver
end
但是Rails在super
的after_teardown
调用中回滚数据库。因此,在Capybara等待会话结束之前,数据库已经回滚。
在super
之后移动Capybara.reset_sessions!
做了伎俩(将其放入def teardown
也是有意义的,这很可能是我们将要做的)。
感谢@ThomasWalpole指出我正确的方向。