You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

使用Rspec和Capybara测试带文件上传的表单提交时遇异常

Rails + Capybara/Cuprite:上传文件时表单提交失败,跳转至空白根路径

问题场景

  • Rails 6.1.4 + Ruby 3.1.3项目,表单包含1个文件上传输入框和3个文本输入框
  • 开发、生产环境下功能完全正常,但使用RSpec+Capybara执行系统测试时出现异常:
    • 当通过attach_file上传图片并点击提交按钮后,请求无法到达控制器方法,页面直接跳转到根路径/并显示空白,测试失败
    • 仅填写文本字段不上传文件时,请求可正常到达控制器,测试流程符合预期

Gemfile配置

gem 'capybara', '~> 3.35', '>= 3.35.3'
gem 'cuprite', '~> 0.13'
gem 'factory_bot_rails', '~> 6.1'
gem 'rspec-rails', '~> 5.0.0'

测试代码

require 'system_helper'

RSpec.describe 'Organization', type: :system do
  let(:user) { create :user }

  signed_in_as :user

  scenario 'User creates an organization with photo', js: true do
    visit new_organization_path

    fill_in 'organization[name]', with: 'Foo'
    fill_in 'organization[location]', with: 'Bar'
    fill_in 'organization[info]', with: 'Baz'

    # 注释此部分后请求可正常到达控制器
    page.attach_file(Rails.root.join('spec/fixtures/images/image.PNG')) do
      page.find('span', text: 'No File Selected').click
    end

    click_on 'Create Organization'

    # 应跳转到该组织的详情页
    expect(page).to have_content 'Foo'
  end
end

排查与解决方案

1. 修正attach_file的使用方式

Cuprite基于Chrome DevTools协议,对文件上传的处理无需模拟点击隐藏的UI元素。原代码中通过block触发点击的方式可能导致文件未正确附加,引发表单提交异常。直接定位文件输入框并附加文件:

# 替换原attach_file代码,通过name/id定位文件输入框
attach_file 'organization[photo]', Rails.root.join('spec/fixtures/images/image.PNG'), make_visible: true
  • make_visible: true用于处理CSS隐藏的文件输入框,确保Capybara能正确定位
  • 若文件输入框有明确的id,也可使用attach_file :organization_photo, ...

2. 验证文件路径与权限

  • 确认测试用的图片文件spec/fixtures/images/image.PNG存在,且测试进程拥有读取权限
  • 可在测试代码开头添加验证:
    expect(File.exist?(Rails.root.join('spec/fixtures/images/image.PNG'))).to be true
    

3. 检查表单的multipart属性

确保Rails表单设置了multipart: true,否则文件无法正确上传,测试环境可能因此触发异常跳转:

<%= form_with model: @organization, html: { multipart: true } do |f| %>
  <!-- 表单字段 -->
<% end %>

4. 查看详细日志定位问题

  • 运行测试时开启debug级日志:
    RAILS_LOG_LEVEL=debug rspec spec/system/organizations_spec.rb
    
  • 检查log/test.log,确认是否有请求记录、参数错误或文件上传相关的异常信息
  • 为Cuprite添加日志输出,排查浏览器端交互问题:
    # 在spec/support/system_helper.rb中配置
    Capybara.register_driver :cuprite do |app|
      Capybara::Cuprite::Driver.new(app, driver_options: { logger: Logger.new(STDOUT) })
    end
    

内容的提问来源于stack exchange,提问作者AlanMendicutti

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.22 09:27:37