RSpec-什么时候应该为每个规范使用一个断言?

RSpec-什么时候应该为每个规范使用一个断言?,rspec,Rspec,据我所知,坚持单一断言规则的主要好处是,在运行测试套件时,您可以更全面地了解测试套件的状态。与失败然后不运行后续断言不同,您可以确切地看到有多少断言失败 这就是说,遵守这一规则与不遵守这一规则之间的绩效差异是显著的。就开发时间而言,随着时间的推移,它也会增加持续集成平台(如CircleCI)的成本 如果我们看一下我写的这个测试示例: describe 'success' do before do result end it 'returns a user' do e

据我所知,坚持单一断言规则的主要好处是,在运行测试套件时,您可以更全面地了解测试套件的状态。与失败然后不运行后续断言不同,您可以确切地看到有多少断言失败

这就是说,遵守这一规则与不遵守这一规则之间的绩效差异是显著的。就开发时间而言,随着时间的推移,它也会增加持续集成平台(如CircleCI)的成本

如果我们看一下我写的这个测试示例:

describe 'success' do
  before do
    result
  end

  it 'returns a user' do
    expect(result[0]).to eq(user)
  end

  it 'returns a success message' do
    expect(result[1]).to eq('Successfully registered')
  end

  it 'queries the user repository' do
    expect(user_repo).to have_received(:find_by).with(email: email)
  end

  it 'generates a hashed password' do
    expect(generate_hashed_password).to have_received(:call).with(password: password)
  end

  it 'creates the user in the database' do
    expect(user_repo).to have_received(:create).with(params[:user])
  end
end
然后在不使用单一断言规则编写的同一测试中:

describe 'success' do
  before do
    result
  end

  it 'creates a user' do
    expect(result[0]).to eq(user)
    expect(result[1]).to eq('Successfully registered')
    expect(user_repo).to have_received(:find_by).with(email: email)
    expect(generate_hashed_password).to have_received(:call).with(password: password)
    expect(user_repo).to have_received(:create).with(params[:user])
  end
end
在我看来,在这种情况下,这个规则不值得坚持。规范不仅可读性更高,而且性能大约是规范的两倍,这带来了真正有益的结果

所以我的问题是——什么时候应该坚持单一断言规则,什么时候打破它更好?

我引用了

。。 在独立单元规范中,您希望每个示例指定一个(且仅一个)行为。同一示例中的多个期望是您可能指定多个行为的信号。 无论如何,在非孤立的测试中(例如,与DB、外部Web服务或端到端测试集成的测试),反复执行相同的设置会带来巨大的性能损失,只是为了在每个测试中设置不同的期望。在这些较慢的测试中,我认为可以指定多个孤立的行为

所以,只要赞成者不如反对者重要,“规则”就应该被打破。我认为,更重要的是,在始终牢记测试目的的情况下,仔细地构建测试,决定测试什么和不测试什么。 最后,测试只是编码。 一个好的测试应该告诉你的代码,应该让你了解你的意图,灵活地实现你的公共接口

如果要做到这一点,你必须在一个
it
里面放上两个
expect
,我会说去做