使用 Capybara/Rspec 的间歇性功能测试失败:期望 { click }.to change { ... }
Intermittent failing feature tests using Capybara/Rspec: expect { click }.to change { ... }
我们有一些功能规范偶尔会失败,重新运行可以修复。我在 Capybara 时间测试方面有很多经验,但在这种特殊情况下,我实际上不确定如何修复它。尝试对此进行网络搜索出奇地无效。
这是我们的失败代码:
expect {
click_on 'Save'
}.to change { Report.count }.from(1).to(2)
我可以想到几种不同的方法来做到这一点:
expect(Report.count).to eq 1
click_on 'Save'
expect(Report.count).to eq 2
或者也许:
expect(Report.count).to eq 1
click_on 'Save'
expect(page).to have_something
expect(Report.count).to eq 2
但鉴于这些测试的失败如此随机且不频繁,因此很难测试我们是否做对了。
根据在 Capybara 中的点击验证 count
更改的正确方法是什么?
首先,在 feature/system 测试中直接进行数据库检查(我假设这就是您正在编写的内容,因为您使用的是 Capybara 通常是一种糟糕的代码味道,因为您通常应该通过视觉变化来验证事物页面(它们对 request/controller 测试更有意义)。
如果您坚持直接进行数据库功能测试,您仍然需要使用视觉检查来同步这些检查。这是因为像 click_on
这样的操作不知道这些点击启动的任何进一步的浏览器操作,并且可以在点击后立即 return 。由于 count
在处理请求后才会真正更改,因此您需要延迟到该请求完成(通常通过等待指示它已完成的可见页面更改来完成)。因此正确的方法是
expect(Report.count).to eq 1
click_on 'Save'
expect(page).to have_something # wait for something that indicates the request triggered by click_on has completed
expect(Report.count).to eq 2
也可以写成
expect {
click_on 'Save'
expect(page).to have_something
}.to change { Report.count }.from(1).to(2)
或更灵活地
expect {
click_on 'Save'
expect(page).to have_something
}.to change { Report.count }.by(1)
我们有一些功能规范偶尔会失败,重新运行可以修复。我在 Capybara 时间测试方面有很多经验,但在这种特殊情况下,我实际上不确定如何修复它。尝试对此进行网络搜索出奇地无效。
这是我们的失败代码:
expect {
click_on 'Save'
}.to change { Report.count }.from(1).to(2)
我可以想到几种不同的方法来做到这一点:
expect(Report.count).to eq 1
click_on 'Save'
expect(Report.count).to eq 2
或者也许:
expect(Report.count).to eq 1
click_on 'Save'
expect(page).to have_something
expect(Report.count).to eq 2
但鉴于这些测试的失败如此随机且不频繁,因此很难测试我们是否做对了。
根据在 Capybara 中的点击验证 count
更改的正确方法是什么?
首先,在 feature/system 测试中直接进行数据库检查(我假设这就是您正在编写的内容,因为您使用的是 Capybara 通常是一种糟糕的代码味道,因为您通常应该通过视觉变化来验证事物页面(它们对 request/controller 测试更有意义)。
如果您坚持直接进行数据库功能测试,您仍然需要使用视觉检查来同步这些检查。这是因为像 click_on
这样的操作不知道这些点击启动的任何进一步的浏览器操作,并且可以在点击后立即 return 。由于 count
在处理请求后才会真正更改,因此您需要延迟到该请求完成(通常通过等待指示它已完成的可见页面更改来完成)。因此正确的方法是
expect(Report.count).to eq 1
click_on 'Save'
expect(page).to have_something # wait for something that indicates the request triggered by click_on has completed
expect(Report.count).to eq 2
也可以写成
expect {
click_on 'Save'
expect(page).to have_something
}.to change { Report.count }.from(1).to(2)
或更灵活地
expect {
click_on 'Save'
expect(page).to have_something
}.to change { Report.count }.by(1)