I recently added the Codacy Github app to my team's main project to help identify possible code issues. One of the features that Codacy offers is tracking test coverage over time, but it's not very clear how to set it up, so I thought I'd write down the steps that ended up working for me.

This assumes you've already set up the simplecov gem, that you've signed up with Codacy, and added your Github repo.

Add a gem to format your test coverage

Add the simplecov-lcov gem to the test area of your gemfile.

# Gemfile

group :test do
  gem 'simplecov-lcov', require: false
end

Then bundle.

> bundle install

Format your test coverage

Use the formatter when you run your tests on Heroku. I put the formatter code between requiring the simplecov gem and the code where I start running simplecov.

# test/test_helper.rb

require 'simplecov'

# add the following 5 lines
require 'simplecov-lcov'
if ENV['CI'].present?
  SimpleCov::Formatter::LcovFormatter.config.report_with_single_file = true
  SimpleCov.formatter = SimpleCov::Formatter::LcovFormatter
end

# starting simplecov right after this
SimpleCov.start 'rails' do
  ...

Create a test script that also sends coverage data

I saved the following script as bin/run_tests_and_save_coverage in my Rails project's bin folder.

#!/bin/bash

# exit when any command fails
set -e

# run tests and save exit code
rails test
export TEST_EXIT_CODE=$?

# send coverage data to Codacy
bash <(curl -Ls https://coverage.codacy.com/get.sh) report -r coverage/lcov/app.lcov

# exit with the test code from the test run
exit $TEST_EXIT_CODE

You can find more info on the Codacy coverage tool here.

Run your new script on Heroku

Change the command in your app.json file to use the new script when testing on CI. Look for the keys environments > test > scripts > test and replace the value with the bash script you created in the last step. There will probably be lots of other things in your app.json file, so don't be confused by my short example here.

{
  "environments": {
    "test": {
      "scripts": {
        "test": "bin/run_tests_and_send_coverage"
      }
    }
  }
}

My app.json file previously said "rails test" here.

Enjoy

Hope this helps. If you run into any issues, feel free to email me.