Capybara:如何确定存在的元素数量

时间:2013-06-08 20:03:18

标签: ruby-on-rails testing cucumber capybara integration-testing

我已将整个堆栈从基于Rails 3.0的项目升级到3.1。我有规格通过,但我的功能现在有点挑剔。我目前面临的问题是这一步:

Then /^I should see (\d+) menu item(?:s)? within "([^"]*)"$/ do |count, selector|
  page.find(:css, selector, :count => count.to_i)
end

在功能本身中,我可能会说:

Then I should see 5 menu items within "tr#menu_item_row"

我得到的信息是:

Then I should see 5 menu items within "tr#menu_item_row"                                      # features/step_definitions/admin_menu_steps.rb:1
  Ambiguous match, found 5 elements matching css "tr#menu_item_row" (Capybara::Ambiguous)
  ./features/step_definitions/admin_menu_steps.rb:2:in `/^I should see (\d+) menu item(?:s)? within "([^"]*)"$/'
  features/admin_menu.feature:30:in `Then I should see 5 menu items within "tr#menu_item_row"'

据我所知,5个元素与实际找到的5个元素匹配。我是否将此代码编写错误或是否有重大变更?谢谢!

2 个答案:

答案 0 :(得分:15)

如果要检查5个元素,则默认情况下不应使用#find,因为Capybara 2.0此方法如果找到多于或少于一个元素,则始终抛出异常。这是故意的,(我相信)是一个很好的改变。

要声明存在5个元素,适当的方法是rspec匹配器:

expect(page).to have_css(selector, count: count.to_i)

我不推荐@fontno推荐的to set match to prefer_exact,因为在find找到多个元素时,你希望Capybara抛出异常的大多数情况。

答案 1 :(得分:2)

是的,这是版本1.x和2.x之间的变化。您可以查看capybara upgrade guide和此blog post中的所有更改。

如果找到多个元素,find方法现在会引发ambiguous match错误。如果你只有几个例子,你可以做这样的事情

Then /^I should see (\d+) menu item(?:s)? within "([^"]*)"$/ do |count, selector|
  page.find(:css, selector, :count => count.to_i, match: prefer_exact)
end

或者如果您有许多这样的示例,您可以更改capybara配置以实现向后兼容性,类似这样的

Capybara.configure do |config|
  config.match = :prefer_exact
  config.ignore_hidden_elements = false
end

您可能需要对其进行修改才能使其正常工作,但这是一般的想法。看看我上面提到的链接,它们都在那里。希望这能让你朝着正确的方向前进