Rails 4集成测试:Capybara与Poltergeist存根问题求助
兄弟,我之前在Rails 4用Poltergeist测JS请求也踩过类似的坑,咱们一步步来排查解决:
1. 先揪出具体报错信息(重中之重!)
你只提到了报错,但没说具体是什么错误——是Net::OpenTimeout、Poltergeist::JavascriptError还是跨域拦截提示?不过根据你推测的外部连接问题,大概率是Poltergeist默认的外部请求限制在搞鬼。
2. 调整Poltergeist的外部请求限制
Poltergeist(基于PhantomJS)默认会阻止所有外部域名的请求,防止测试被第三方服务干扰。如果你的create方法里调用了外部API、加载了外部CDN资源,就会触发这个限制。
你可以在rails_helper.rb里修改Poltergeist配置,按需放开限制:
Capybara.register_driver :poltergeist do |app| Capybara::Poltergeist::Driver.new(app, { # 临时放开所有外部请求(测试环境用,上线前记得改回) phantomjs_options: ['--web-security=no', '--ignore-ssl-errors=yes'], # 更严谨的做法:只允许指定域名 # url_whitelist: ['your-allowed-domain.com', 'another-allowed-domain.com'], # 如果有无关JS报错干扰,也可以先关掉JS错误检测 # js_errors: false }) end
注意:
--web-security=no会关闭跨域安全检查,适合快速验证问题,但不建议长期开启,最好用url_whitelist精确管控允许的域名。
3. 确认format.js的响应是否符合预期
你提到create方法返回JSON响应,但format.js默认是渲染JS模板。如果要返回JSON,得在action里明确指定:
def create # ...你的业务逻辑 respond_to do |format| format.js { render json: @your_model.to_json } end end
如果模板不存在或者响应格式不对,Poltergeist也会抛出JS加载失败的错误,容易被误以为是网络问题。
4. 检查测试代码的等待逻辑
JS测试是异步的,触发请求后要等待AJAX完成和页面更新,不然会出现断言失败:
scenario "creates record via JS", js: true do fill_in "Name", with: "Test Record" click_button "Create" # 等待页面反馈(比如提示文案出现) expect(page).to have_content("Record created successfully") end
如果没加等待,可能会出现“元素不存在”的错误,和网络问题混淆。
5. 排查版本兼容性问题
Rails 4对应的Poltergeist版本对PhantomJS有版本要求:比如Poltergeist 1.x对应PhantomJS 1.9.x,2.x对应PhantomJS 2.x。版本不兼容会出现各种奇怪的网络/JS错误,你可以运行phantomjs -v查看版本,然后调整Gemfile里的Poltergeist版本。
内容的提问来源于stack exchange,提问作者DaniG2k

