9

我在我的 Cucumber 功能中添加了一个 Around 钩子,我希望在抛出异常时会导致 pry-rescue 开始 pry:

Around do |scenario, block|
  Pry::rescue do
    block.call
  end
end

肯定会调用 Around 钩子,但是不会挽救步骤中引发的异常。例如这一步:

When(/^I perform the action$/) do
  raise 'hell'
end

... 导致该功能失败,但不会让我在控制台上窥探。

可以对 Cucumber 使用 pry-rescue 吗?我也将此作为一个问题提出,因为我怀疑它可能是一个错误。

更新:根据评论中 AdamT 的建议,我:

  • @allow-rescue标签添加到调用故意破坏步骤的功能中
  • 添加了puts日志以验证Around钩子是否被调用

引发异常时仍然无法进入 pry,但我可以从puts语句中看到它正在进入 Around 钩子。

4

3 回答 3

7

我想做同样的事情——当一个步骤失败时进行调试。您的钩子无法工作,因为已经捕获了失败的步骤异常。似乎没有标准的方法可以用黄瓜做你想做的事。但是如果你看一下lib/cucumber/ast/step_invocation.rb方法invoke(runtime, configuration),你就会明白我在说什么。

在方法步骤级别的异常被捕获。最后一个rescue块是我们要插入调试代码的地方。所以在最新的cucumber1.3.12 中,我在第 74 行插入了:

        require 'byebug'
        byebug

现在一旦发生瞬时故障,我会收到提示:

[71, 80] in /home/remote/akostadi/.rvm/gems/ruby-2.1.1/gems/cucumber-1.3.10/lib/cucumber
/ast/step_invocation.rb
   71:             failed(configuration, e, false)
   72:             status!(:failed)
   73:           rescue Exception => e
   74:             require 'byebug'
   75:             byebug
=> 76:             failed(configuration, e, false)
   77:             status!(:failed)
   78:           end
   79:         end
   80:       end

不过,您可以在其中插入其他调试代码。

我在想黄瓜项目是否会接受捐款以在那里有一个钩子。

更新:这是我的最新版本。该版本的优点是您在进入调试器之前会获得失败日志。您也可以(至少用撬)到达黄瓜World并在里面启动撬来玩弄,就好像这是您的测试代码一样。我已经在 cuke google 小组中进行了讨论,看看是否可以在上游实现类似的东西。如果你想让黄瓜成为标准,请给出你的声音和建议。所以只需将以下代码放入support/env.rb

  Cucumber::Ast::StepInvocation.class_eval do
    ## first make sure we don't lose original accept method
    unless self.instance_methods.include?(:orig_accept)
      alias_method :orig_accept, :accept
    end

    ## wrap original accept method to catch errors in executed step
    def accept(visitor)
      orig_accept(visitor)
      if @exception
        unless @exception.class.name.start_with?("Cucumber::")
          # @exception = nil # to continue with following steps
          # cd visitor.runtime/@support_code
          # cd @programming_languages[0].current_world
          # binding.pry
          require 'pry'
          binding.pry
        end
      end
    end
  end
于 2014-03-26T08:02:30.460 回答
1

在 Cucumber 2.4.0 版本中,该#accept方法位于其中,Cucumber::Formatter::LegacyApi::Ast::StepInvocation因此重新定义它并在其中执行所需的操作:

Cucumber::Formatter::LegacyApi::Ast::StepInvocation.class_eval do
  alias_method :orig_accept, :accept

  def accept formatter
    orig_accept(formatter)
    if status == :failed
      formatter.runtime.support_code.ruby.current_world.instance_eval do
        # do something as if you are inside the cuke test step
        # like: expect(something).to be_something_else
      end
    end
  end
end
于 2016-11-07T13:25:57.103 回答
-1

你有没有试过打电话:

binding.pry

只需在失败的测试中调用它并环顾四周。

于 2013-10-23T04:31:47.297 回答