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

批量运行Devise相关系统测试失败,单独运行正常(Devise::Mailer报错)

问题

在基于Ruby on Rails 7、集成Devise的应用中使用RSpec进行系统测试时,遇到以下异常现象:

  • 单独运行每个系统测试用例时全部通过;
  • 批量运行所有系统测试时,所有与Devise相关(确认、密码、注册、会话、解锁)的测试都会报错:

ActionView::Template::Error: undefined local variable or method `controller' for #Devise::Mailer:0x0000000007fb98

  • 仅重新批量运行这些失败的测试时,它们又全部通过。

以下是用户注册相关的失败测试示例:

RSpec.describe 'Registrations: signing up user', :type => :system do
  describe 'sign up user' do
    before(:each) do
      @regular_user = FactoryBot.build(:regular_user)

      visit new_user_registration_path
    end

    it 'should sign up user', :js => true do
      within("#form_id") do
        fill_in_sign_up_user_form(@regular_user.username, @regular_user.email, @regular_user.password)
      end

      expect(page).to have_current_path(root_path)

      # ...
    end
  end
end

请问Devise::Mailer在批量运行时出现该问题的原因是什么,如何解决?


原因与解决方案

核心原因

这个问题本质是Devise邮件器(Devise::Mailer)在批量测试时丢失controller上下文,或是自定义Devise邮件模板错误引用了controller变量——Devise::Mailer继承自ActionMailer::Base,本身并不具备controller实例方法,该变量仅存在于控制器上下文当中。

批量测试触发、单独/重跑失败测试又恢复正常,通常源于:

  1. 测试间的状态残留,某一测试修改了邮件器全局配置/上下文,影响后续测试;
  2. 并行测试(若开启)的进程间状态冲突;
  3. 特定Devise版本存在系统测试场景下的上下文丢失bug。

解决方案

1. 检查并修复自定义Devise邮件模板

如果项目修改过Devise的邮件模板(如app/views/devise/mailer/confirmation_instructions.html.erb等),排查是否存在controller变量引用:

  • 错误示例:<%= controller.root_url %>
  • 替换为直接调用路由辅助方法:<%= root_url %>(邮件模板可直接使用路由辅助方法,无需依赖controller)

2. 确保测试环境邮件配置完整

在config/environments/test.rb中确认ActionMailer的默认URL配置,避免邮件模板生成时依赖上下文:

config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }
config.action_mailer.delivery_method = :test # 测试环境默认配置,确保未被修改

3. 强化测试间的状态隔离

在RSpec配置文件(spec/rails_helper.rb或spec/spec_helper.rb)中添加钩子,确保每个系统测试后清理邮件器状态:

RSpec.configure do |config|
  config.after(:each, type: :system) do
    # 清空已发送邮件队列
    ActionMailer::Base.deliveries.clear
    # 若有自定义邮件器的全局状态,在此同步重置
  end
end

4. 禁用并行测试(若开启)

如果使用了parallel_tests等并行测试工具,暂时禁用并行运行,验证是否为进程间状态冲突导致的问题。若禁用后恢复正常,再针对并行环境调整邮件器隔离配置。

5. 更新Devise到最新稳定版

部分旧版本Devise在系统测试批量运行时存在上下文丢失bug,更新到最新稳定版(参考Devise官方版本日志)可能直接解决问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.02 03:04:53