【问题标题】:Is shoulda destroying my backtraces?应该破坏我的回溯吗?
【发布时间】:2010-11-18 11:26:00
【问题描述】:

我有一个或多或少这样的测试:

class FormDefinitionTest < ActiveSupport::TestCase
  context "a form_definition" do
    setup do
      @definition = SeedData.form_definition
      # ...

我特意加了一个

raise "blah"

在路上的某个地方,我收到了这个错误:

RuntimeError: blah
test/unit/form_definition_test.rb:79:in `__bind_1290079321_362430'

当我应该得到一些东西时:

/Users/pupeno/projectx/db/seed/sheet_definitions.rb:17:in `sheet_definition': blah (RuntimeError)
    from /Users/pupeno/projectx/db/seed/form_definitions.rb:4:in `form_definition'
    from /Users/pupeno/projectx/test/unit/form_definition_test.rb:79

任何想法是什么在清理/破坏我的回溯?我的怀疑是应该,因为异常发生在设置中的时间或者应该是它发生的原因。

这是一个 Rails 3 项目,以防万一。

【问题讨论】:

  • 如果你想引发一些异常,为什么要引发这个问题?如果它是一个测试,它不是该做的格式。
  • @shingara 我这样做只是为了看看它的样子。真正发生的是,我从某个地方得到一个异常,另一个异常,但我找不到在哪里,因为某些东西隐藏了大部分回溯。
  • 您报告的所有堆栈跟踪都来自您的“raise blah”。所以我不明白你真正的问题
  • @shingara:我的问题是,当错误发生在从 setup 或 should 调用的方法中时,堆栈跟踪不包含直到 raise 本身的所有帧。 form_definition_test.rb:79 不会引发“废话”,它是由另一个方法调用的方法引发的,正如您在第二个堆栈跟踪中看到的那样。
  • @J. Pablo Fernandez:如果您添加raise "blah" 以发布一个最小(可重现)示例,如果您可以发布一个我们可以自己运行(无需自己添加任何代码)来重现的最小示例,我们将不胜感激问题。

标签: ruby-on-rails ruby testing shoulda backtrace


【解决方案1】:

那是因为 shoulda 方法 #context 正在为您生成代码。对于每个 #should 块,它会为您生成一个完全独立的测试,例如

class FormDefinitionTest < ActiveSupport::TestCase
  context "a form_definition" do
    setup do
      @definition = SeedData.form_definition
    end

    should "verify some condition" do
      assert something
    end

    should "verify some other condition" do
      assert something_else
    end
  end
end

那么#should会生成两个完全独立的测试(对于#should的两个调用),一个会执行

      @definition = SeedData.form_definition
      assert something

另一个执行

      @definition = SeedData.form_definition
      assert something_else

值得注意的是,它不会生成一个测试,依次执行所有三个步骤。

这些生成的代码块具有类似 _bind_ 的方法名称,并且生成的测试的名称是遍历到 should 块的所有上下文名称加上应该块提供的字符串(前缀为“应该 ”)。有another example in the documentation for shoulda-context

【讨论】:

    【解决方案2】:

    我认为这将为您提供所需的回溯。我还没有测试过,但它应该可以工作:

    def exclude_backtrace_from_location(location)
      begin
        yeild
      rescue => e
        puts "Error of type #{e.class} with message: #{e.to_s}.\nBacktrace:"
        back=e.backtrace
        back.delete_if {|b| b~=/\A#{location}.+/}
        puts back
      end
    end
    
    exclude_backrace_from_location("test/unit") do
      #some shoulda code that raises...
    end
    

    【讨论】:

      【解决方案3】:

      你检查过config/initializers/backtrace_silencers.rb吗?这是自定义该行为的入口点。使用Rails.backtrace_cleaner.remove_silencers!,您可以清理消音器堆栈。

      更多关于ActiveSupport::BacktraceCleaner的信息请见here

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2011-08-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多