How do I get the current test file name from RSpec?

I am trying to speed up large RSpec projects. In addition to using the RSpec option, --profile

I wanted to get the longest test files [1].

In mine, spec_helper.rb

I am dumping the tested classes and the total time per file, however, since we have directories spec/model

and spec/request

, I would really like to be able to print the current test file name, not just the class name ( described_class

), so that the user can eliminate the double deviation between model/foo_spec.rb

and request/foo_spec.rb

when optimizing.

In block before

c spec/spec_helper.rb

, how can I get the current filename of the test file?

Mine (heavily cropped) spec_helper

looks like this:

config.before :all do
  @start_time =

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

config.after :suite do
  timing_logfile_name = 'log/rspec_file_times.log'
  timing_logfile = "#{File.dirname(__FILE__)}/../#{timing_logfile_name}"
  file =, '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]) )
  tell_if_verbose("Overall test times are logged in '#{timing_logfile_name}'")


This doesn't sound like curpecn RSpec metadata, but I hope someone more familiar with internals can think of a way to expose it. Thanks, Dave

[1] Often a file with, say, 100 examples in it gives a higher speed than one example from -profile, when this large file before :each

/ before :all

blocks is targeted, obviously even the saved ms is multiplied by the number of tests in the file. Using this technique in addition to --profile

me helped a lot.


source to share

1 answer

As long as you're just using this to profile your tests to determine which files need to be improved, you should be able to add this to your file spec_helper.rb

(and remove it afterwards). I totally understand that this is not pretty / clean / elegant / acceptable in production environments, and I disavow that I ever wrote this :)

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




All Articles