首页 文章

使用pry-rescue来调试Cucumber步骤中的异常

提问于
浏览
7

我已经为我的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

...导致该功能失败,但不会让我在控制台撬到它 .

是否有可能使用黄瓜撬救?我也把它作为一个issue,因为我怀疑它可能是一个bug .

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

  • @allow-rescue 标记添加到调用故意破坏步骤的功能中

  • 添加了 puts 日志以验证是否正在调用 Around 挂钩

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

3 回答

  • 1

    我想做同样的事情 - 在步骤失败时进行调试 . 您的钩子无法工作,因为已经捕获了失败的步骤异常 . 似乎没有标准的方法来做你想要的黄瓜 . 但如果你看 lib/cucumber/ast/step_invocation.rb 方法,你会看到我在说什么 .

    在方法步骤中捕获异常 . 最后一个 rescue 块是我们要插入调试代码的地方 . 所以在最近的 cucumber 1.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 并启动里面的撬来玩,好像这是你的测试代码 . 我打开了一个discussion in the cuke google group,看看是否可以在上游实现类似的东西 . 如果你想让它成为黄瓜标准,请给出你的声音和建议 . 所以只需将下面的代码放在 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
    
  • 6

    在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
    
  • 0

    你试过打电话:

    binding.pry
    

    只需在失败的测试中调用它并浏览一下 .

相关问题