47

I have a library consisting of several packages. When running tests, I am using '-cover' flag and its showing the coverage information for each package individually.Like follows:

--- PASS: TestSampleTestSuite (0.00s)
PASS
coverage: 28.7% of statements
ok      github.com/path/to/package1 13.021s
?       github.com/path/to/package2 [no test files]

=== RUN   TestAbc
--- PASS: TestAbc (0.43s)
PASS
coverage: 27.7% of statements

Is there any way to get a full coverage overview easily to get good idea about coverage on the whole project?

Update: Here is the go test command I am using

go test ./... -v -short -p 1 -cover
Jonathan Hall
  • 75,165
  • 16
  • 143
  • 189
Rana
  • 5,912
  • 12
  • 58
  • 91

1 Answers1

54

EDIT: Things have changed since I wrote this answer. See the release notes of Go 1.10: https://golang.org/doc/go1.10#test :

The go test -coverpkg flag now interprets its argument as a comma-separated list of patterns to match against the dependencies of each test, not as a list of packages to load anew. For example, go test -coverpkg=all is now a meaningful way to run a test with coverage enabled for the test package and all its dependencies. Also, the go test -coverprofile option is now supported when running multiple tests.

You can now run

go test -v -coverpkg=./... -coverprofile=profile.cov ./...
go tool cover -func profile.cov

Old answer

Here is a bash script extracted from https://github.com/h12w/gosweep :

#!/bin/bash
set -e

echo 'mode: count' > profile.cov

for dir in $(find . -maxdepth 10 -not -path './.git*' -not -path '*/_*' -type d);
do
if ls $dir/*.go &> /dev/null; then
    go test -short -covermode=count -coverprofile=$dir/profile.tmp $dir
    if [ -f $dir/profile.tmp ]
    then
        cat $dir/profile.tmp | tail -n +2 >> profile.cov
        rm $dir/profile.tmp
    fi
fi
done

go tool cover -func profile.cov
HectorJ
  • 5,814
  • 3
  • 34
  • 52
  • Well, it still shows the coverage info per package basis, which I am getting from my given command. Any tweaks to get a overall coverage info? – Rana Nov 01 '15 at 04:30
  • The very last line it outputs is this : `total: (statements) 99.3%`, is that not what you want @Rana ? – HectorJ Nov 01 '15 at 05:48
  • 1
    I got the "bad mode line" too. I had to add the line `echo "mode: count" > profile.cov` in the beginning. – nboon Jun 17 '18 at 10:39
  • Thanks, added to the answer – HectorJ Jun 17 '18 at 10:41
  • 2
    Am I right in thinking this only produces a coverage for those files that have some tests? Also I had to add `-not -path './vendor/*'` to ignore vendored packages. – danielcooperxyz Aug 22 '18 at 11:10
  • 2
    @danielcooperxyz is correct. Packages which don't have tests will produce a 1-line profile containing `mode: count`. The tail command will remove this line and append nothing to profile.cov. This then prevents `go tool cover -func profile.cov` from accurately calculating the total coverage. For what it's worth, `go test -coverprofile=profile.cov ./...` is functionally equivalent to most of this script and suffers from the same inaccuracy. – Alex Jansen Dec 11 '19 at 09:37
  • How are the added flags in go 1.10 relevant for this? – Johannes Riecken Mar 17 '20 at 15:08
  • 1
    @rubystallion added an example on how to use them – HectorJ Mar 18 '20 at 10:25
  • In my particular case, continue not very pretty, but it works `line_total=$(go tool cover -func profile.cov | grep -e 'total:')` next `total_int=$(echo "$line_total" | grep -o '[0-9.]*' | awk '{print int($1+0.5)}')` finally the comparison in case of requiring to inform `if (( $total_int < $threshold )) ; then` – Sebastian Correa Zuluaica Apr 15 '22 at 04:02