Simplecov: Include code that is not being called in reports

Created on 10 Nov 2014  路  10Comments  路  Source: simplecov-ruby/simplecov

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

Most helpful comment

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}

All 10 comments

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}
Was this page helpful?
0 / 5 - 0 ratings