ruby-on-rails 随机种子在rspec中失败,但本身未失败

at0kjp5o  于 2023-05-02  发布在  Ruby
关注(0)|答案(3)|浏览(155)

我遇到了一个问题,运行一个规格测试在一个随机的种子顺序。当我自己运行测试时,它通过了,这真的让我很沮丧。我该怎么解决这个问题?

describe MarketingInfo do
let(:question)       { create(:marketing_question) }
let(:answer)         { create(:marketing_answer, marketing_question:      question) }

let(:marketing_info) { MarketingInfo.new(create(:account)) }

describe '#create' do
let(:result) { marketing_info.create(info) }

context 'when valid' do
  let(:info) { { question.id => answer.id }  }
  specify { expect(result).to be_true }
end

context 'when invalid' do
  let(:info) { { question.id => '' } }
  specify { expect(result).to be_false }
end
end

def initialize(answerable)
   @answerable = answerable
   @marketing_responses = []
 end

def create(response_data)
  response_data.each do |question_id, answer_array|
    m_response = build_marketing_response(question_id, answer_array)
    @marketing_responses << m_response if m_response
end

valid?
end

以下是使用随机种子运行时的失败消息:

1) MarketingInfo#create when valid should be true
 Failure/Error: specify { expect(result).to be_true }
   expected: true value
        got: false
 # ./spec/form_objects/marketing_info_spec.rb:29:in `block (4 levels) in <top (required)>'
oknwwptz

oknwwptz1#

另一个调试示例之间相互依赖关系的选项是RSpec Bisect。它将尝试分离出一组可重复性最低的示例:

$ rspec -s 123 --bisect
Bisect started using options: "-s 123"
Running suite to find failures... (1 minute 4.16 seconds)
Starting bisect with 1 failing example and 600 non-failing examples.
Checking that failure(s) are order-dependent... failure appears to be order-dependent

Round 1: bisecting over non-failing examples 1-600 . ignoring examples 1-199 (22.55 seconds)
Round 2: bisecting over non-failing examples 200-400 .. ignoring examples 421-400 (28.87 seconds)
Round 3: bisecting over non-failing examples 300-350 .. multiple culprits detected - splitting candidates (37.26 seconds)
Round 4: bisecting over non-failing examples 330-335 .. multiple culprits detected - splitting candidates (43.32 seconds)
...
Bisect complete! Reduced necessary non-failing examples from 600 to 10 in 25 minutes 16 seconds.

The minimal reproduction command is:
  rspec './spec/controllers/etc_controller_spec.rb[1:1:1,1:1:2,1:2:1,1:3:1]' './spec/models/thing_spec.rb[1:1:2:1,1:1:2:2]' ... -s 123

喂养一颗已知会失败的种子可以加快速度。

pvcm50d1

pvcm50d12#

当您运行RSpec测试时,它们单独运行,并且作为一个组通过但失败,这可能意味着几件事(我从经验中学习)。有时可能是因为套房有异味,物品的顺序是依赖的。不过,听起来不是这个问题。否则,这可能意味着数据库在运行测试时没有以您期望的方式响应。
无论如何,我发现this blog post对于调试这类情况特别有用(它让您检查失败测试的specs.log文件,以查看测试前发生了什么)。
也许你应该在每个测试运行后清除你的示例变量?

8xiog9wr

8xiog9wr3#

对于后代来说,当一个测试孤立地不稳定时,它可能依赖于系统的非决定性部分,如系统时间、随机数或网络连接。
当一个测试在与其他测试一起运行时是不稳定的(特别是当改变测试的顺序导致不稳定时),这意味着一些其他测试正在将状态泄漏到环境中,并导致不稳定的测试失败,因为它对环境的假设不再正确。
而且,当一个测试在CI上并行运行时不稳定,这可能是由于两个测试都访问同一个全局状态之间的竞争条件。
我在这个question上给出了更详细的答案。

相关问题