Skip to content
Actionable code coverage.
Branch: master
Clone or download
Fetching latest commit…
Cannot retrieve the latest commit at this time.
Permalink
Type Name Latest commit message Commit time
Failed to load latest commit information.
lib
specs support test_ which some minitest projects use May 9, 2019
.gitignore implement Apr 17, 2016
.travis.yml
Gemfile
Gemfile.lock v1.3.2 May 9, 2019
MIT-LICENSE initial by http://github.com/grosser/project_template Apr 16, 2016
Rakefile silence warnings Dec 5, 2016
Readme.md coverage image May 19, 2019
single_cov.gemspec mark required ruby version Dec 10, 2016

Readme.md

Single Cov Build Status coverage

Actionable code coverage.

rspec spec/foobar_spec.rb
......
114 example, 0 failures

lib/foobar.rb new uncovered lines introduced (2 current vs 0 configured)",
Uncovered lines:
lib/foobar.rb:22
lib/foobar.rb:23:6-19
  • Missing coverage on every 💚 test run
  • Catch coverage issues before making PRs
  • Easily add coverage enforcement for legacy apps
  • 2-5% runtime overhead on small files, compared to 20% for SimpleCov
  • Branch coverage on ruby 2.5+ (disable via branches: false)
  • Use with forking_test_runner for per test coverage
# Gemfile
gem 'single_cov', group: :test

# spec/spec_helper.rb ... load before loading rails / minitest / libraries
require 'single_cov'
SingleCov.setup :rspec

# spec/foobar_spec.rb ... add covered! call to test files
require 'spec_helper'
SingleCov.covered!

describe "xyz" do ...

Minitest

Call setup before loading minitest.

SingleCov.setup :minitest
require 'minitest/autorun'

Unfound target file

# change all guessed paths
SingleCov.rewrite { |f| f.sub('lib/unit/', 'app/models/') }

# mark directory as being in app and not lib
SingleCov::APP_FOLDERS << 'presenters'

# add 1-off
SingleCov.covered! file: 'scripts/weird_thing.rb'

Known uncovered

Add the inline comment # uncovered to not be alerted about it being uncovered.

Prevent addition of new uncovered code, without having to cover all existing code.

Alternatively mark how many lines are uncovered:

SingleCov.covered! uncovered: 4

Verify all code has tests & coverage

# spec/coverage_spec.rb
SingleCov.not_covered! # not testing any code in lib/

describe "Coverage" do
  it "does not allow new untested code" do
    # option :tests to pass custom Dir.glob results
    SingleCov.assert_used
  end

  it "does not allow new untested files" do
    # option :tests and :files to pass custom Dir.glob results
    # :untested to get it passing with known untested files
    SingleCov.assert_tested
  end
end

Automatic bootstrap

Run this from irb to get SingleCov added to all test files.

tests = Dir['spec/**/*_spec.rb']
command = "bundle exec rspec %{file}"

tests.each do |f|
  content = File.read(f)
  next if content.include?('SingleCov.')

  # add initial SingleCov call
  content = content.split(/\n/, -1)
  insert = content.index { |l| l !~ /require/ && l !~ /^#/ }
  content[insert...insert] = ["", "SingleCov.covered!"]
  File.write(f, content.join("\n"))

  # run the test to check coverage
  result = `#{command.sub('%{file}', f)} 2>&1`
  if $?.success?
    puts "#{f} is good!"
    next
  end

  if uncovered = result[/\((\d+) current/, 1]
    # configure uncovered
    puts "Uncovered for #{f} is #{uncovered}"
    content[insert+1] = "SingleCov.covered! uncovered: #{uncovered}"
    File.write(f, content.join("\n"))
  else
    # mark bad tests for manual cleanup
    content[insert+1] = "# SingleCov.covered! # TODO: manually fix this"
    File.write(f, content.join("\n"))
    puts "Manually fix: #{f} ... output is:\n#{result}"
  end
end

Author

Michael Grosser
michael@grosser.it
License: MIT

You can’t perform that action at this time.