如果rspec测试失败,请启动ruby调试器

时间:2013-04-30 00:26:07

标签: ruby-on-rails rspec ruby-debug pry

通常情况下,当测试失败时,我会花一些时间试图找出导致测试失败的原因。如果RSpec在测试失败时启动Ruby调试器会很有用,这样我就可以立即检查局部变量以深入了解原因。

我正在使用的解决方案现在看起来像这样:

# withing some test
debugger unless some_variable.nil?
expect(some_variable).to be_nil

然而,这种方法很麻烦,因为我首先等待测试失败,然后添加调试器行,修复问题然后必须删除调试器行,而我希望它更像gdb它可以在命中异常时启动,而不需要使用debugger语句来编写代码库。

编辑:我试过普利茅斯。它对我来说还不够可靠。此外,开发历史似乎表明它不是一个非常受支持的宝石,所以我宁愿不依赖它。

更新:我试用pry-rescue并发现它很整洁。但是,我经常使用zeus,并且想知道是否有办法让它与pry-rescue一起使用。

7 个答案:

答案 0 :(得分:25)

使用pry-rescue,它是普利茅斯的精神继承者:

来自自述文件:

如果您正在使用RSpec或respec,您可以使用rescue rspec或rescue respec在每次测试失败时打开一个pry会话:

$ rescue rspec
From: /home/conrad/0/ruby/pry-rescue/examples/example_spec.rb @ line 9 :

     6:
     7: describe "Float" do
     8:   it "should be able to add" do
 =>  9:     (0.1 + 0.2).should == 0.3
    10:   end
    11: end

RSpec::Expectations::ExpectationNotMetError: expected: 0.3
     got: 0.30000000000000004 (using ==)
[1] pry(main)>

答案 1 :(得分:6)

如果没有debugger在块的范围内,您将无法轻松访问本地变量,但RSpec为您提供了周围的钩子,让您这样做:

config.around(:each) do |example|
  result = example.run
  debugger if result.is_a?(Exception)
  puts "Debugging enabled"
end

此时您可以访问@ivarssubject / let(:var)内容。

答案 2 :(得分:3)

我喜欢@ jon-rowe的解决方案(不需要额外的宝石)进行轻微编辑:我真的不关心其他错误RSpec::Expectations::ExpectationNotMetError

  config.around(:each) do |example|
    example.run.tap do |result|
      debugger if result.is_a?(RSpec::Expectations::ExpectationNotMetError)
    end
  end

答案 3 :(得分:1)

您需要在构造ExpectationNotMatched异常时捕获它。在某个地方的助手中包含以下代码,RSpec将在构造异常时停止。这将在匹配器内部的几个级别,所以在调试器中,说“where”然后“up 5”或“up 6”,你将在你的块的instance_exec内。调试器没有在我正在使用的版本中正确显示代码,但是您可以再次“启动”并获得在评估测试的相同上下文中运行的代码,这样您就可以检查实例变量(但是似乎不是局部变量。

require 'debugger'
require 'rspec'

Debugger.start
class RSpec::Expectations::ExpectationNotMetError
  alias_method :firstaid_initialize, :initialize

  def initialize *args, &b
    send(:firstaid_initialize, *args, &b)
    puts "Stopped due to #{self.class}: #{message} at "+caller*"\n\t"
    debugger
    true # Exception thrown
  end
end

describe "RSpec" do
  it "should load use exceptions on should failure" do
    @foo = :bar    # An instance variable I can examine
    1.should == 2
  end
end

答案 4 :(得分:1)

来自 Rspec 文档:

<块引用>

RSpec 尝试提供有用的失败消息,但对于需要更具体信息的情况,您可以在示例中定义自己的消息。这适用于除运算符匹配器之外的任何匹配器。

我所做的是在该消息中调用 pry。看例子:

describe "failing" do
  context "test" do
    it "should start pry" do
      a = 3
      b = 1
      expect(a).to be == b, "#{require 'pry';binding.pry}"
    end
  end

调试愉快!

答案 5 :(得分:0)

您可以使用 plymouth gem https://github.com/banister/plymouth。它使用 pry ,但是(更好)替代 irb

HTH

答案 6 :(得分:-1)

您可以尝试hammertime。每当发生异常时,它都会停止并提示您进入交互式调试会话。