Track test coverage on Codacy with Rails + Heroku CI
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.