加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

ruby-on-rails – 使用RSPEC进行测试时突然出现无法解释的活动记

发布时间:2020-12-17 02:40:52 所属栏目:百科 来源:网络整理
导读:这是我几乎一无所知的地方,所以请提前道歉.我有一套超过800个rspec测试.在运行整个集合或仅仅是特定的测试文件时,突然而且莫名其妙地,在这些之后(例如20个左右,虽然它的数字从不完全相同),每个单独的测试都会以相同的错误开始失败: Failure/Error: Unable t
这是我几乎一无所知的地方,所以请提前道歉.我有一套超过800个rspec测试.在运行整个集合或仅仅是特定的测试文件时,突然而且莫名其妙地,在这些之后(例如20个左右,虽然它的数字从不完全相同),每个单独的测试都会以相同的错误开始失败:

Failure/Error: Unable to find matching line from backtrace
 ActiveRecord::ConnectionTimeoutError:
   could not obtain a database connection within 5.000 seconds (waited 5.000 seconds)

在典型的运行中,我会在20次左右的请求测试后开始收到这些错误,剩下的780次测试都会因上述完全相同的错误而失败.我已经尝试回到之前测试完美的git提交和分支.没有运气 – 仍然有780次失败.还完全删除了重新创建的测试数据库.也没有运气.

我已经阅读了许多关于连接池等的线程,但我恐怕我不知道如何诊断甚至正在发生的事情.以下是我现在所知道的事实:

>使用Postgresql
>就我所知,开发环境运作良好
>在一切正常的时候和现在之间,我没有对我所知道的环境进行任何更改/升级.甚至没有任何数据库迁移.仅仅更改模型,视图和控制器代码.正如我所提到的,回到之前的提交并没有解决任何问题.
> config.helper.rb中的config.use_transactional_fixtures = false,因为我正在通过Selenium测试ajax功能.
>然而,无论Selenium是否用于特定的测试集,测试都会失败.即使我只运行不使用Selenium的测试,在20次左右的测试后仍然会出现故障.

我使用Database Cleaner而不是事务夹具,具有以下配置:

config.before(:suite) do
    DatabaseCleaner.clean_with(:truncation)
  end

  config.before(:each) do
    DatabaseCleaner.strategy = :transaction
  end

  config.before(:each,:js => true) do
    DatabaseCleaner.strategy = :truncation
  end

  config.before(:each) do
    DatabaseCleaner.start
  end

  config.after(:each) do
    DatabaseCleaner.clean
  end

有什么想法在这里发生了什么?更具体地说,我应该在哪些想法看看问题是什么?我几乎没有处理此类ActiveRecord问题的经验,我甚至不知道从哪里开始.

更新虽然我仍然不知道为什么会发生这种情况,但我确实知道导致它的代码是什么.在最近的提交中,我添加了在新线程中发送通知电子邮件.这是代码:

def teacher_notification_email
      Thread.new do
        UserMailer.accepted_parent_invitation_email(@parent_profile).deliver
        ActiveRecord::Base.connection.close
      end
    end

我在应用程序的许多其他地方使用了这个确切的模式(使用不同的电子邮件),所有这些都经过测试.出于某种原因,这个特定的原因导致数据库超时错误.关于为什么会发生这种情况的任何想法都是受欢

更新
由于我不是在理解线程在这种情况下如何工作的阶段,我不知道问题的确切来源,除此之外:从我读过的内容来看,很难以编程方式控制执行以这种方式创建的线程.但是,我找到了解决方案.我已经将块更改为以下块而不是上面的块:

def teacher_notification_email
      if Rails.env.test?
        UserMailer.accepted_parent_invitation_email(@parent_profile).deliver
      else
        Thread.new do
          UserMailer.accepted_parent_invitation_email(@parent_profile).deliver
          ActiveRecord::Base.connection.close
        end
      end
    end

所以我基本上运行不同的代码用于测试而不是开发 – 没有用于测试的新线程.我认为这是一个坏主意,但直到我能够理解真正的问题所在(由于某种原因本身不会失败的测试,或仍然使用不会强制测试失败的线程的代码),是我需要的.

最后更新

我已经删除了异步发送电子邮件的Thread.new方法,而是实现了Sidekiq.这是一个更多的工作,但它运作良好,测试很好……

解决方法

这似乎与在生成的线程中触摸活动记录有关.看起来db连接在收到之前不会返回池中.我已经能够通过明确要求提前连接并在完成后关闭它来解决此问题.试试这个:

Thread.new do
    ActiveRecord::Base.connection_pool.with_connection do |conn|
        UserMailer.accepted_parent_invitation_email(@parent_profile).deliver
    end
end

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读