Feature: generate coverage only for specific file under test
hi there, great gem!
Apologies if there is already a documented way to do this but I was wondering if there was a way to have coverage generated only for the single file being tested by a single unit test?
So for example, say that I have an rspec file spec/foo_spec.rb and it has contents like:
describe Foo do
it 'should work' do
expect(described_class.new.work).to be_true
end
end
and another file lib/foo.rb with contents like
class foo
def work
true
end
def something_else
false
end
And imagine we have lots of other specs and code too. Would it be possible so that when we focus on the specific test foo_spec.rb that the coverage report would only display coverage for foo.rb and not for any other files, as a way of providing a quick check of whether that specific test is fully coveraging the file it is responsible for?
I'm thinking particularly of using this in combination with simplecov-console so that I could be running a single test like so, and getting really tightly focused output on that one file I'm interested in:
$ rspec spec/foo.rb
Run options: include {:focus=>true}
...
Finished in 1.54 seconds (files took 3.9 seconds to load)
3 examples, 0 failures
COVERAGE: 62.70% -- 4/7 lines in 1 file
showing bottom (worst) 1 of 1 file
+----------+------------------+-------+--------+-------------+
| coverage | file | lines | missed | missing |
+----------+------------------+-------+--------+-------------+
| 26.09% | lib/foo.rb | 6 | 3 | 5-7 |
+----------+------------------+-------+--------+-------------+
Note - follows on from discussion in https://github.com/chetan/simplecov-console/issues/14
:wave:
Hi there!
There's no documented way of doing this. It should automatically happen though if only that one single file was required and no other call to track_files or something like that happens.
Otherwise, dynamically calling out to whatever we do with #696 or so should probably solve this problem :)
thanks, that's interesting - I guess that's RSpec automatically requiring all the files ... hmm ...
rspec shouldn't automatically do that iirc but most people will require lots of files in their spec_helper which makes this harder :)
So, I guess us providing an option you can call to limit the tracked files to that.
A workaround while that feature isn't avaiable would be to add_filter everything but the file that's not very feasible though :sweat_smile:
Related to #696
I'm not sure whether this has been tackled or not, but following @PragTob workaround, you can accomplish it with a single add_filter:
SimpleCov.start do
add_filter do |file|
File.basename(file.filename) != `foo.rb`
end
end
I use something like that:
SimpleCov.start 'rails' do
spec_paths = ARGV.grep %r{(spec)/\w+}
if spec_paths.any?
file_paths = spec_paths.map { |spec_path| spec_path.gsub(%r{spec/|_spec}, "") }
add_filter do |file|
file_paths.none? do |file_path|
if file.filename.include? "/app/"
file.filename.match?(%r{/app/#{file_path}})
else
file.filename.include?(file_path)
end
end
end
end
end
So for example if I run:
rspec spec/models/user_spec.rb spec/lib/middlewares --format documentation
Then spec_paths is ["spec/models/user_spec.rb", "spec/lib/middlewares"] and file_paths is ["models/user.rb", "lib/middlewares"]. Therefore, any files not including "app/models/user.rb" and "lib/middlewares" will be filtered.
It's not bulletproof obviously, but it does the job...
I've created a gem for a similar use case. Any comments are welcome. https://github.com/floor114/simplecov-single_file
Is there any way to stop simplecov in between if i want? . I am not sure if this is the correct portal to ask this. can anybody help me ? . @floor114 @PragTob