CI环境Capybara3.35.3+Rails6.1.3测试报60秒请求未完成错误,本地正常
Capybara CI 测试
Requests did not finish in 60 seconds 报错排查指南 报错本质
该错误由 Capybara 内置测试服务器中间件触发:每次测试结束重置会话时,中间件会追踪所有未完成的后端请求,等待60秒仍无响应即抛出异常。当前使用环境为 Capybara 3.35.3 + Rails 6.1.3,本地测试通过、CI 失败的核心原因分两类:CI 环境下请求执行耗时超过默认阈值,或测试页面存在未正常终止的后台异步请求。
从堆栈信息看,当前挂起的请求路径为 /test_metadata/digital_object_identifiers/4/register。
分步排查与解决方案
1. 定位目标请求在CI环境的阻塞原因
- 在目标接口对应的 Controller 动作入口、出口添加日志,确认接口实际执行的耗时点:重点检查是否存在依赖外部第三方服务、大事务查询、文件IO操作的逻辑,CI 容器的网络访问限制、资源配额不足都可能导致这类操作被阻塞。
- 对比本地与 CI 的测试环境配置:确认是否本地测试时通过 mock 跳过了外部依赖调用,而 CI 环境未正确加载对应的测试 mock 配置,导致真实请求被发送后无法收到响应。
2. 调整超时配置适配CI环境性能
如果排查确认接口在 CI 环境下的执行耗时略高于本地(因资源受限普遍慢20%-40%),可直接修改 Capybara 的等待阈值,在测试初始化配置文件(通常为 spec/support/capybara.rb)中添加以下配置:
# 调整会话重置时等待 pending 请求的最长时间,默认值为60秒 Capybara.register_server :puma do |app, port, host| Rack::Server.start( app: app, Host: host, Port: port, Environment: "test", Silent: true, Timeout: 120 ) end # 全局调整 Capybara 默认等待时间 Capybara.default_wait_time = 120
3. 处理未闭环的异步请求
如果接口本身已执行完成、仍被标记为 pending,说明存在未正常终止的前端异步请求:
- 检查测试页面是否存在定时轮询、页面卸载时未主动取消的 AJAX、长连接 WebSocket 逻辑:这类请求会在 Capybara 重置会话关闭页面时被中间件标记为未完成。
- 在测试用例结束前,主动等待页面所有后台请求执行完成,避免在请求处理过程中触发会话重置:
# 等待前端自定义的 pending 请求计数清零 wait_until { page.evaluate_script('window.pendingAjaxRequests === 0') } # 等待页面加载状态标识消失 expect(page).to have_no_css('.global-loading')
4. 优化测试服务器的CI运行配置
CI 容器通常对 CPU 资源做了硬限制,Capybara 默认的单线程 Puma 模式容易出现请求排队超时:
- 切换为多线程服务器模式,提升请求处理能力:
Capybara.server = :puma_threaded - 控制 CI 环境下的测试并行度,避免因过度抢占资源导致请求处理阻塞。
内容的提问来源于stack exchange,提问作者varun
相关产品推荐
相关产品推荐

