1. Computing

Keeping Organized in SimpleCov

By

Filters and Groups

This article is part of a series. For more information, see Code Coverage with SimpleCov.

In the previous article, we looked at the very basics of SimpleCov, a code coverage library. In this article, we'll look at two very important features offered by SimpleCov: filters and groups. Filters allow you to ignore the reports for some files. In our case, we'll want to ignore coverage for the tests themselves. Groups allow you to group files into separate tabs for easy navigation.

Basic Configuration

SimpleCov configuration is typically done by passing a block to the SimpleCov.start method. This block is executed to provide a type of configuration Domain Specific Language. The methods we're really interested in here will be:

  • add_filter - Adds a filter to the filter list. The filter list is a list of strings, if any filename contains any of the strings, it won't be included in the coverage report. For example, if you put the "/spec/" string in the filter list, any file whose path contains /spec/ (with the slashes, this is a string, not a Regexp literal) will not be included in the output. Be careful though, if you happen to have another spec directory with files you are interested in, you will need to write a more specific filter for that directory.
  • add_group - This adds a group to the group list. A group consists of a group name and a string to match filenames against, much like the filter list. All files that match this string will be included in a tab in the output HTML. Also, instead of a string you may also pass a block, a SourceFile object will be passed and this allows you to group more accurately and also by factors such as file size or contents.
  • coverage_dir - Normally, the coverage directory is ./coverage, but you can change it to anything you need here.
  • project_name - Here you can define a more descriptive project name, otherwise it just uses the directory name of your project. This can be particularly useful if you send this coverage report to someone else who might have different directory names.

Running SimpleCov

The previous dice example from the last article isn't really appropriate for this article. For this article, we'll grab this example Rails project, though any larger project, or really any Rails project with at least a model or two, a few controllers, etc will work well. The following commands will get the tests for the Rails Tutorial up and running quickly.


$ git clone https://github.com/RailsApps/learn-rails.git
$ bundle install
$ cp config/database.yml{.example,}
$ rake db:create
$ rake db:migrate
$ rake spec

If everything went right you should see the rspec tests run (and hopefully no tests fail). Time to add code coverage. Where you do this exactly depends on which test suite you're using. This project uses rspec, so the file we want to edit is spec/spec_helper.rb, which is required before any tests are run. But first, make bundler happy by changing part of your Gemfile.


group :test do
  gem 'selenium-webdriver', '2.0.0'
  gem 'capybara', '2.1.0'
  gem 'factory_girl_rails', '4.2.0'
  gem 'cucumber-rails', '1.3.0', :require => false
  gem 'database_cleaner', github: 'bmabey/database_cleaner'
  gem 'simplecov', :require => false

And edit spec/spec_helper.rb.


Spork.prefork do
  unless ENV["DRB"]
    require 'simplecov'
    SimpleCov.start
  end

Now run rake spec again and open coverage/index.html. You should see a full coverage report. It's a long list of files, completely unorganized and even contains a few irrelevant files. It's time to fix that.

Groups and Filters

The first thing to do to clean this up is to start adding groups. There are three very obvious groups for a Rails project: models, views and controllers. Since these are already organized neatly into directories, we want groups to match /app/models/, /app/controllers/ and /app/views/. We'll also throw in helpers matched with /app/helpers/.

The configuration of SimpleCov is, as mentioned above, done by passing a block to SimpleCov.start.


Spork.prefork do
  unless ENV["DRB"]
    require 'simplecov'
    SimpleCov.start do
      add_group 'Models', '/app/models/'
      add_group 'Controllers', '/app/controllers/'
      add_group 'Views', '/app/views/'
      add_group 'Helpers', '/app/helpers/'
    end
  end

If you re-run the tests, you'll see that there are new multiple tabs across the top of the page. You can see the files that didn't make it into any groups in the "ungrouped" tab. There, you'll see some irrelevant files. We don't test the configuration files, and we don't really care about coverage on the tests themselves (they're usually very simple and linear anyway). So let's add some filters. We don't care about the /spec/ or /config/ directories.


Spork.prefork do
  unless ENV["DRB"]
    require 'simplecov'
    SimpleCov.start do
      add_group 'Models', '/app/models/'
      add_group 'Controllers', '/app/controllers/'
      add_group 'Views', '/app/views/'
      add_group 'Helpers', '/app/helpers/'

      add_filter '/config/'
      add_filter '/spec/'
    end
  end

Et voilá! Since Rails is so well organized, that was quite easy. On larger projects, that process might take longer. And of course, SimpleCov does come with Rails support out of the box, but that doesn't teach you anything about configuring SimpleCov. Instead of doing all that, you could simply do SimpleCov.start 'rails'. There are just a few more configuration options to explore, the project name and coverage directory.


Spork.prefork do
  unless ENV["DRB"]
    require 'simplecov'
    SimpleCov.start do
      add_group 'Models', '/app/models/'
      add_group 'Controllers', '/app/controllers/'
      add_group 'Views', '/app/views/'
      add_group 'Helpers', '/app/helpers/'

      add_filter '/config/'
      add_filter '/spec/'

      project_name 'Rails Tutorial Sample App'
      coverage_dir 'cov'
    end
  end
  1. About.com
  2. Computing
  3. Ruby
  4. Gems
  5. SimpleCov
  6. Filtering and Groups

©2014 About.com. All rights reserved.