通常情况下,当测试失败时,我会花一些时间试图找出导致测试失败的原因。如果RSpec在测试失败时启动Ruby调试器会很有用,这样我就可以立即检查局部变量以深入了解原因。
我正在使用的解决方案现在看起来像这样:
# withing some test
debugger unless some_variable.nil?
expect(some_variable).to be_nil
然而,这种方法很麻烦,因为我首先等待测试失败,然后添加调试器行,修复问题然后必须删除调试器行,而我希望它更像gdb
它可以在命中异常时启动,而不需要使用debugger
语句来编写代码库。
更新:我试用pry-rescue
并发现它很整洁。但是,我经常使用zeus,并且想知道是否有办法让它与pry-rescue
一起使用。
答案 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
此时您可以访问@ivars
和subject
/ 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。每当发生异常时,它都会停止并提示您进入交互式调试会话。