Is it possible to have SimpleCov include models and controllers that aren't being called by tests? I'm currently getting a too high coverage percentage because SimpleCov only shows includes files that have tests in the report.
Using Rails + MiniTest
I'm not sure I understand your question. Are you asking if it is possible to report coverage for untested files? If so, yes. SimpleCov will record all executed code from the moment it is started. Any file that is loaded will have some code in it executed, and hence some coverage.
Check the top of your Rakefile and see https://github.com/colszowka/simplecov/issues/340
I'm closing this assuming the explanation solves your problem. Please re-open if it does not.
Thanks @bf4 , I read through the linked issue but I'm still not sure what to do.
Here's the situation:
I create a brand new Rails 4.1 project with some controllers and models. As per the readme, I add:
gem "simplecov", :require => false, :group => :test
At the very top of my test/test_helper.rb, as per the readme:
require "simplecov"
SimpleCov.start "rails"
Now, if I haven't written tests for all of my controllers and models, the files are not included in the coverage report when running tests with rake test. I would expect them to show up with 0% coverage.
I was under the impression that Rails loads classes lazily? So I'm not sure where those files would be required unless I require them manually or reference them from within a test?
Without more code it's hard to tell exactly what you're experiencing.
Does it really matter, though, if a file was loaded or not? Any loaded file will have some positive 'coverage'. What you should be interested in is whether the methods in those files (that don't execute when the file is loaded) were exercised by the tests.
Try adding this to your test helper
END { puts $LOADED_FEATURES.join("\n") }
When the test finishes running, it will print out all the files Ruby loaded and their order. It should give you some more insight. coverage.so is when SimpleCov loads Ruby's Coverage module
Also, with Rails you should probably put the require and start at the top of the Rakefile, but I don't think that's causing what you're seeing.
@bf4 I created a gist here https://gist.github.com/jensljungblad/39af8c014f1449a008ba with a rails template, so that hopefully you can see what I'm trying to explain.
Run it with
rails new foobar -m https://gist.githubusercontent.com/jensljungblad/39af8c014f1449a008ba/raw/bb89d49644b9e6867f284f15c6f909fb4a51b098/simplecov_template.rb
As you can see it generates two resources, article and comment. But comment is generated without tests. If you run the tests and open the coverage report, you'll see that the comments_controller.rb and comment.rb are missing from the report, because they were never required.
I would prefer if they would show up, but with a coverage of 0%. That would make the coverage percentage accurate. As it is now, someone could add a bunch of features without tests, and the coverage wouldn't change. That seems wrong to me.
So, what you're suggesting is that SimpleCov glob all the files in the current directory, check how many lines there are in each, and if they weren't executed, report 0% coverage with how many lines are in it? The logic to determine which files weren't run that you want to know they weren't run but didn't expect them to be run can get a little complicated. Perhaps you could extend the formatter to manually add 0% coverage for the files you're interested in including in the report but that you're not loading?
Nothing will ever be 0% and show up on the report unless the file literally has no code in it.
The only way to make sure all files show up would be that when you are running with coverage, use eager loading or something like
files = `git ls-files`.chomp.split("\n").map(&:strip)
ruby_files = files.select {|file| File.extname(file) == '.rb' }
ruby_files.each do |ruby_file|
begin
require ruby_file
rescue LoadError, NameError, NoMethodError
STDERR.puts "Could not load #{ruby_file}: #{$!.class} #{$!.message}"
end
end
Try putting these lines in a new order: in spec_helper.rb
require 'simplecov'
SimpleCov.start('rails')
does it help?
This is very old but for anyone reaching here googling like i did => See: https://github.com/colszowka/simplecov/issues/401. My controllers were not included in the coverage report because no rspec test were accesing them. Now they are. I just added the line Dir[Rails.root.join("app/controllers/api/v1/**/*.rb")].each {|f| require f} in the rails_helper.rb file. The line may vary depending on your directory structure. Rails 5 --api mode, rspec 3.7
The coverage library relies on the code being loaded to determine whether it's covered. You can also hardcore set files we should load and count as not loaded
Based on @tommyalvarez's comment I did this as a generic solution:
rails_helper.rb
require 'rspec/rails'
# ...
Dir[Rails.root.join("app/**/*.rb")].each {|f| require f}
Dir[Rails.root.join("lib/**/*.rb")].each {|f| require f}
Most helpful comment
Based on @tommyalvarez's comment I did this as a generic solution:
rails_helper.rb