8

我已经将我的整个堆栈从基于 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 个元素相匹配。我是写错了这段代码还是发生了重大变化?谢谢!

4

2 回答 2

15

如果要检查 5 个元素,则#find默认情况下不应使用自 Capybara 2.0 以来,如果发现多于或少于一个元素,此方法总是会引发异常。这是一个有意的(我相信)一个很好的改变。

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

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

我不建议按照@fontno 的建议设置matchprefer_exactfind,因为在大多数情况下,如果发现多个元素,您希望 Capybara 抛出异常。

于 2013-06-08T21:05:36.550 回答
2

是的,这是 1.x 和 2.x 版本之间的变化。您可以查看capybara 升级指南和此博客文章中的所有更改。

如果找到多个元素,该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

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

于 2013-06-08T20:47:57.837 回答