【问题标题】:How to get the current test filename from RSpec?如何从 RSpec 获取当前的测试文件名?
【发布时间】:2012-03-27 13:57:14
【问题描述】:

我正在尝试加快大型 RSpec 项目的测试。除了使用 RSpec 的 --profile 选项之外,我还想打印出运行时间最长的测试文件 [1]。

在我的spec_helper.rb 中,我将正在测试的类和总时间转储到一个文件中,但是由于我们有spec/modelspec/request 目录,我真的希望能够打印当前测试的文件名 而不仅仅是类名(described_class),以便用户在优化时可以消除model/foo_spec.rbrequest/foo_spec.rb 之间的歧义。

spec/spec_helper.rbbefore 块中,如何获取当前测试文件的文件名?

我的(严重修剪)spec_helper 看起来像这样:

config.before :all do
  @start_time = Time.now
end

config.after :all do |test|
  timings.push({ :name => test.described_class,
                 :file => 'I do not know how to get this',
                 :duration_in_seconds => (Time.now - @start_time) })
end

config.after :suite do
  timing_logfile_name = 'log/rspec_file_times.log'
  timing_logfile = "#{File.dirname(__FILE__)}/../#{timing_logfile_name}"
  file = File.open(timing_logfile, 'w')
  timings.sort_by{ |timing| timing[:duration_in_seconds].to_f }.reverse!.each do |timing|
    file.write( sprintf("%-25.25s    % 9.3f seconds\n",
                        timing[:name], timing[:duration_in_seconds]) )
  end
  file.close
  tell_if_verbose("Overall test times are logged in '#{timing_logfile_name}'")
end

这似乎在当前的 RSpec 元数据中不可用,但我希望更熟悉内部结构的人能想出一种方法来公开它。谢谢, 戴夫

[1] 通常,一个包含 100 个示例的文件比来自 --profile 的单个示例产生更快的速度 - 当以该大文件的 before :each / before :all 块为目标时,显然甚至节省了一毫秒乘以文件中的测试数。除了--profile 之外,使用这种技术对我有很大帮助。

【问题讨论】:

    标签: ruby-on-rails ruby rspec rspec2


    【解决方案1】:

    只要您只是使用它来分析您的测试以确定哪些文件需要改进,您应该能够将它扔到您的spec_helper.rb 文件中(然后将其删除)。我完全理解这在生产环境中并不漂亮/干净/优雅/不可接受,我否认我曾经写过它:)

    config.before(:each) do |example|
      path = example.metadata[:example_group][:file_path]
      curr_path = config.instance_variable_get(:@curr_file_path)
      if (curr_path.nil? || path != curr_path)
        config.instance_variable_set(:@curr_file_path, path)
        puts path
      end
    end
    

    【讨论】:

    • 谢谢;这并没有直接解决我当前的问题,因为我似乎只有在之前的示例元数据:每个,而不是:所有。但是,我可以重写,直到足够接近我想要的为止。
    • 是的,在 :all 之前没有获取元数据,但这实际上是在做每个测试/示例并在源文件更改时打印出来。如果您想更深入地挖掘,请在 config.before(:all) 中放置一个“pp config”调用,然后执行一个测试以转储配置对象中的所有内容。你可能会在那里找到一些我错过的有用的东西。
    • 为了访问example,我必须将config.before(:each) do 更改为config.before(:each) do |example|(即我需要添加|example|)。我认为这是由于 RSpec 的一些变化,因为这个答案最初是写的。 (我目前使用的是 RSpec 版本 3.7.0。)
    猜你喜欢
    • 1970-01-01
    • 2012-09-26
    • 2013-10-31
    • 1970-01-01
    • 1970-01-01
    • 2011-12-09
    • 1970-01-01
    • 2016-05-04
    • 2022-12-25
    相关资源
    最近更新 更多