First impressions of Ruby branch coverage with DeepCover

Branch coverage for Ruby is finally on the horizon! The built-in coverage library is expected to ship in Ruby 2.5 with branch and method coverage options.

And a pure-Ruby gem is in development, too: DeepCover.

I gave DeepCover a try with my main project, the Wiki Education Dashboard, and the coverage of the Ruby portions of the app dropped from 100% to 96.75%. Most of that is just one-line guard clauses like this:

return unless Features.wiki_ed?

But there are a few really useful things that DeepCover revealed. First off, unused scopes on Rails ActiveRecord models:

class Revision < ActiveRecord::Base
  scope :after_date, ->(date) { where('date > ?', date) }
end

Unlike default line coverage, DeepCover showed that this lambda wasn’t ever actually used. It was dead code that I removed today.

Similarly, DeepCover shows where default arguments in a method definition are never used, like this:

class Article < ActiveRecord::Base
  def update(data={}, save=true)
    self.attributes = data
    self.save if save
  end
end

This method was overriding the ActiveRecord update method, adding an option to update without saving. But we no longer use that second argument anywhere in the codebase, meaning I could delete the whole method and rely on the standard version of update.

4 thoughts on “First impressions of Ruby branch coverage with DeepCover”

  1. DeepCover co-author here. Thanks for the great examples. The unused scope is probably fairly typical. You mention unused default arguments (which DeepCover can detect), but in the update case, I imagine that the default argument was always used (which we should detect) and that it’s actually DeepCover’s branch coverage that alerted you to the face that `if save` was always true, right?

    1. I think it’s that the default argument was always used, but it was detecting that nothing *except* the default argument was used. I’m not completely sure, though.

      The `def` line is the one that was marked as uncovered. (I did this via simplecov, so I didn’t get the visualization of the uncovered parts within the line.)

Leave a Reply

Your email address will not be published. Required fields are marked *