Then /^my application domain results should be:$/ do |table|
table.rows.each do |row|
row_id = dom_id_for(row[0])
cell_id = dom_id_for(row[0], row[1], row[2])
page.should have_css "tr##{row_id}"
begin
page.should have_xpath("//td[@id='#{cell_id}'][text()=\"#{row[3].strip.lstrip}\"]")
rescue Capybara::ExpectationNotMet => exception
# find returns a Capybara::Element, native returns a Selenium::WebDriver::Element
contents = find(:xpath, "//td[@id='#{cell_id}']").native.text
puts "Expected #{ row[3] } for #{ row[0,2].join(' ') } but found #{ contents } instead."
@step_failures_were_rescued = true
end
end
end
然后我在features / support / hooks.rb中定义一个钩子,如:
After do |scenario|
unless scenario.failed?
raise Capybara::ExpectationNotMet if @step_failures_were_rescued
end
end
3 回答
我认为实现所需行为的唯一方法(这是非常罕见的)是定义自定义步骤并自己捕获异常 . 根据cucumber wiki步骤失败,如果它引发错误 . 几乎所有默认步骤都会引发错误,如果他们能够捕获此异常,则该步骤将被标记为已通过,但在救援中您可以提供自定义输出 . 另外我建议你仔细定义你想要捕获的异常,我想如果你只是从ElementNotFound异常中找到页面上的一个元素,请不要捕获所有异常 .
问题很老,但希望这会有所帮助 . 我正在做的事情有点“错误”,但它确实有效 . 在您的Web步骤中,如果您想继续,您必须捕获异常 . 我这样做主要是为了添加有用的失败消息 . 我正在检查一个充满了Cucumber中标识的值的表,其中包含一堆行,例如:
标识符在应用程序域中有意义,并以人性化的方式在结果表中命名特定单元格 . 我有帮助器将人类标识符转换为DOM ID,用于首先检查我正在寻找的行是否存在,然后在该行的单元格中查找特定值 . 缺失行的默认失败消息对我来说足够清楚(期望找到css“tr#my_specific_dom_id”但没有匹配) . 但是检查单元格中特定文本的失败消息完全没有用 . 所以我做了一个捕获异常的步骤,并使用Cucumber步骤信息和一些元素搜索来获得一个很好的失败消息:
然后我在features / support / hooks.rb中定义一个钩子,如:
这使得整个场景失败,但它掩盖了Cucumber的步骤失败,因此所有步骤结果都是绿色的,包括那些不正确的步骤 . 您必须看到方案失败,然后回顾消息以查看失败的情况 . 这对我来说似乎有些“坏”,但它确实有效 . 在我的情况下更方便的是获得在我正在检查的整个表的域友好上下文中列出的预期值和找到的值,而不是像“我寻找”$ 123.45这样的消息“但我找不到它 . ”使用Capybara“内部”方法可能有更好的方法 . 这是迄今为止我提出的最好的 .
我和Cucumber开发人员讨论过:他们认为这是一个坏主意:https://groups.google.com/forum/#!topic/cukes/xTqSyR1qvSc很多时候,可以重新设计场景以避免这种需求:场景必须分成几个较小且独立的场景,或者几个检查可以聚合成一个,提供更人性化的场景和更少类似脚本的场景 .
但是,如果你真的需要这个功能,就像我们的项目一样,我们已经完成了Cucumber-JVM的分支 . 这个fork允许你注释步骤,这样当它们以确定的异常失败时,它们将让下一步执行(并且步骤本身被标记为失败) .
fork在这里可用:https://github.com/slaout/cucumber-jvm/tree/continue-next-steps-for-exceptions-1.2.4它只适用于Java语言,很难:例如,欢迎任何帮助使代码适应Ruby . 我认为这不会是很多工作 .