集成测试:`assert_select 'a[href=?]'` 分页页面失败

Integration test: `assert_select 'a[href=?]'` fails for paginated pages

我有很多类似这样的集成测试:

first_page_of_users = User.page(1)                    # Using kaminari for pagination.
first_page_of_users.each do |user|
  assert_select 'a[href=?]', user_path(user)
end

这些测试失败并显示错误消息,例如:

Expected at least 1 element matching "a[href="/users/1"]", found 0..

我将 puts @response.body 添加到测试中以查看它响应的代码。

对于响应正文中包含的所有用户,它都有正确的 href,例如 href="/users/75938613"。但是,/users/ 后面的数字要高得多,而且 "users1" 确实不存在(不仅 url 不存在,整个记录也不在该页面上)。 如果我确保只有少数固定装置以便不应用分页,则测试通过。这让我觉得分页时 first_page_of_users = User.page(1) 应用的顺序与first_page_of_users.each do |user| assert_select 'a[href=?]', user_path(user) 期望的记录顺序...

什么可能导致此错误?它适用于我的应用程序的不同页面和模型。


更新:即使我尝试了另一个模型

Organization.all.each do |org|
  puts @response.body
  assert_select 'a[href=?]', organization_path(org)
end

我收到错误:

Expected at least 1 element matching "a[href="/organizations/fix0"]",

名称为 "fix0" 的组织根本不存在于其响应的正文中。我的(缩短的)固定装置在下面,他们确认不应该有任何组织使用该名称。知道发生了什么事吗?

one:
  name: abcd
  activated: true
  activated_at: 2015-04-16 11:38:53

two:
  name: efgh
  activated: true
  activated_at: 2015-04-16 11:38:53

<% 35.times do |n| %>
organization_<%= n %>:
  name: <%="fix#{n}" %>
  activated: true
  activated_at: <%= Time.zone.now %>
<% end %>

进行集成测试时,重要的是要跟踪应该在何处显示的内容并对其进行测试。因为在这种情况下,第一页的记录太多,任何落在后面页面上的记录都会导致测试失败。正如您所怀疑的,像这样的事情应该验证结果的第一页是否存在:

Organization.order('organizations.name','desc').page(1).each do |organization|
     assert_select 'a[href=?]', organization_path(organization)
end

我建议保留一个较小的数据集用于测试,因为在这种情况下,您还应该 'get' 在测试中的第二页,并对 'page(2)' 进行上述断言。这意味着此集成测试必须发出两个获取请求(加上您可能需要的任何设置)并检查结果,养成这样的习惯会降低您的套件速度。