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