问题
I'm trying to speed up a large RSpec project's tests. In addition to using RSpec's --profile
option I wanted to get the longest running test files [1] printed out.
In my spec_helper.rb
I dump the classes being tested and total time to a file, however as we have spec/model
and spec/request
directories I'd really like to be able to print the current test's filename and not just the class name (described_class
), so that the user can disambiguate between model/foo_spec.rb
and request/foo_spec.rb
when optimizing.
In a before
block in the spec/spec_helper.rb
, how can I get the current test file's filename?
My (heavily trimmed) spec_helper
looks like this:
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
This doesn't seem to be available in the curretn RSpec meta-data, but I'm hoping someone more familiar with the internals can think of a way to expose it. Thanks, Dave
[1] Often a file with, say, 100 examples in it yields more speed up than a single example from --profile - when that large file's before :each
/ before :all
blocks are targetted, obviously even a ms saved is multiplied up by the number of tests in the file. Using this technique in addition to --profile
helped me a lot.
回答1:
As long as you're just using this for profiling your tests to identify which files need to be improved, you should be able to toss this into your spec_helper.rb
file (and remove it afterwards). I fully understand that this is not pretty/clean/elegant/acceptible in production environments and I disavow that I ever wrote it :)
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
来源:https://stackoverflow.com/questions/9891028/how-to-get-the-current-test-filename-from-rspec