Lets say you have an open source project called mypkg
written in Go programming language and you host the repository over at Github (https://github.com/jbub/mypkg). As a proper Go developer you write tests to make sure you code works and you also measure code coverage over time. Your simple project consists of two subpackages called subpkg1
and subpkg2
. The project structure looks roughly like this:
mypkg
├── subpkg1
│ ├── file1.go
│ └── file1_test.go
└── subpkg2
├── file2.go
└── file2_test.go
You write your tests using the great testing
package from the standard library. Go provides you with the go test
command to run those tests from the command line. In order to measure the test coverage you want to run the command with the -coverprofile
flag enabled. This flag defines a path where the test coverage output data will be saved. It can then later be used to visualize or store the coverage data. So lets try to run it:
go test -v ./... -coverprofile=mypkg.coverprofile
But the command fails with:
cannot use test profile flag with multiple packages
Seems like there is currently a limitation of covering a single package at a time in Go 1.9. What you can do is to measure the coverage one package at a time:
go test -v ./subpkg1/... -coverprofile=subpkg1.coverprofile
go test -v ./subpkg2/... -coverprofile=subpkg2.coverprofile
This will output separate .coverprofile
files for each subpackage which is not ideal. You want to publish project code coverage as a whole to a service like Coveralls (https://coveralls.io). You also use a continuous integration service like Travis CI (https://travis-ci.org) to automate the build/test process.
There are two projects that can help us solve this problem:
- gover (https://github.com/sozorogami/gover)
- goveralls (https://github.com/mattn/goveralls)
Gover is actually a really simple Go program that looks at a given directory and collects all of the .coverprofile
files and concatenates them into a single gover.coverprofile
file. On the other hand Goveralls is a Go client for the Coveralls continuous code coverage tracking system.
After we measure the test coverage for each package we can then use gover
to collect all profiles and create a single file from them. We can then take that file and feed it to the goveralls
client to publish the coverage to the Coveralls service. Here is an example .travis.yml
config file for our project that should do the work:
sudo: false
language: go
go:
- 1.9.2
before_install:
- go get github.com/modocache/gover
- go get github.com/mattn/goveralls
script:
- go test -v github.com/jbub/mypkg/subpkg1 -coverprofile=subpkg1.coverprofile
- go test -v github.com/jbub/mypkg/subpkg2 -coverprofile=subpkg2.coverprofile
- gover
- goveralls -coverprofile gover.coverprofile -service travis-ci
NOTE: Do not forget to setup your COVERALLS_TOKEN
environment variable in the travis-ci user interface.
Luckily the Go community identified this and the problem is going to be solved and probably released soon in Go 1.10 (https://github.com/golang/go/issues/6909).