Test Coverage in Go

An important part of the process process of learning a new language is to learn the ecosystem that helps you to write better code. In a previous article I covered gdb integration with Go.

Next on my list is to find an equivalent of the fantastic Python coverage tool coverage.py. The Go equivalent is called gocov.

Let’s go ahead and install it now:

$ go get github.com/axw/gocov/gocov
$ go install github.com/axw/gocov/gocov
The two steps above have compiled and installed a binary gocov progam in your $GOPATH/bin. I would recommend adding this to your $PATH:
export PATH=$PATH:$GOPATH/bin
Now we’re ready to start using gocov in conjunction with our test suite. Here’s an example of running the test suite via gocov, generating a coverage report, and then immediately viewing that report via the less command.
$ gocov test <myprogram> | gocov report | less
If you’ve worked with coverage tools before, the report should look familiar, with a breakdown of each function. Here’s a sample:
[...]
dispatch/dispatch.go     Dispatcher.String               100.00% (8/8)
dispatch/dispatch.go     NewDispatcher                   100.00% (2/2)
dispatch/dispatch.go     Dispatcher.RefreshPlugins       100.00% (2/2)
dispatch/dispatch.go     Dispatcher.Dispatch             83.33% (5/6)
[...]
It is also possible to annotate the source listing of a particular function:
$ gocov test <myprogram> > coverage.json
$ gocov annotate coverage.json dispatch.Dispatcher.Dispatch

33 func (self *Dispatcher) Dispatch(l *line.Line) {
34
35 activePlugins := self.plugins[l.ChatBotId]
36
37 var err error
38 for _, plugin := range activePlugins {
39 err = self.queue.Publish(PUBSUB_PREFIX+plugin.Name, l.AsJson())
40 if err != nil {
41 MISS log.Fatal("Error writing (PUBLISH) to queue. ", err)
42 }
43 }
44 }
This tells us that line 41 isn’t tested. gocov is a convenient tool that helps to guide you in writing tests for your program. Since it outputs to stdout you can use it in conjunction with grep, sort, less, etc. [Edited – 2013-01-09]: Amended the article to reflect the feedback I got on reddit.com/r/golang
Yann Malet

About the author

Yann Malet

Yann is the Director of Engineering at Lincoln Loop, where he leads the engineering team and drives technical excellence. In 2015, Yann co-authored High-Performance Django with Peter Baumgartner. Prior to his involvement with Lincoln Loop, Yann …

View Yann's profile

Recent Insights

Using Django Inside the Tornado Web Server

Inspired by Eric Florenzano’s talk, Using Django in Non-Standard Ways (slides in PDF) at DjangoCon and …

Using Proxy Models to Customize the Django Admin

Fellow Lincoln Looper, Martin Mahner, posted an excellent write up on how to use proxy models …

Custom Filters in the Django Admin

A few weeks ago Django’s team revealed a data leakage bug in the admin application that …