Awesome Go

prettycov

CategoryTesting
SubcategoryTesting Frameworks
Stars3

Draws a Go coverage profile as a package tree with a total on every row

About prettycov

Prettycov

codecov Go Vulnerabilities Release Go Reference License Mentioned in Awesome Go

Go coverage as a tree, with a total on every row.

go tool cover -func gives you one line per function and a single number at the bottom. It gives no total per package, and none across packages at all (golang/go#66506), so "how covered is scraper?" has no answer, and on a real repository you get hundreds of lines to add up yourself.

prettycov reads the profile go test already wrote and answers that:

❯ go test -covermode=atomic -coverprofile=coverage.out ./...
❯ prettycov report
 github.com/screwyprof/delegator - 91.54
 ├ pkg - 93.33
 ├ scraper - 88.00
 └ web - 93.94

Every row is the sum of everything beneath it, so you can start at the top and follow the worst number down.

Status

Pre-1.0. Flags, output format and the Go API may all change between minor versions, so pin a version if you gate CI on it. CHANGELOG.md records what changed and what broke.

Installation

go install github.com/screwyprof/prettycov/cmd/prettycov@latest

What it is for

Deciding what to test next

In the tree below, handler is 87.23% covered and pgxdb/pgxdb.go is 75.00%, but handler has six untested statements to pgxdb's four. The lower percentage is just the smaller file. --counts prints the statement counts alongside, so you can rank by how much is left:

❯ prettycov report --counts --files --depth=2
 github.com/screwyprof/delegator - 91.54  34/402 uncovered
 ├ pkg - 93.33  8/120 uncovered
 │ ├ clock/clock.go - 100.00  0/2 uncovered
 │ ├ httpkit/httpkit.go - 96.30  1/27 uncovered
 │ ├ logger - 92.50  3/40 uncovered
 │ ├ pgxdb/pgxdb.go - 75.00  4/16 uncovered
 │ └ tzkt/client.go - 100.00  0/35 uncovered
 ├ scraper - 88.00  18/150 uncovered
 │ ├ config/config.go - 100.00  0/1 uncovered
 │ ├ service.go - 92.31  5/65 uncovered
 │ ├ store - 74.51  13/51 uncovered
 │ └ subscriber.go - 100.00  0/33 uncovered
 └ web - 93.94  8/132 uncovered
   ├ api/errors.go - 100.00  0/14 uncovered
   ├ handler - 87.23  6/47 uncovered
   ├ store/pgxstore - 95.12  2/41 uncovered
   └ tezos - 100.00  0/30 uncovered

The counts add up the same way: scraper's 18 are service.go's 5 and store's 13.

A number for CI or a badge

total prints the figure and nothing else, so a Makefile can read it. --fail-under gates on it, for the whole profile or for one package:

COVERAGE := $(shell prettycov total)                 # 91.54
❯ prettycov total scraper/store --fail-under=85
74.51
total coverage 74.51% is below 85.00%      # exit 1

A list your editor can open

misses prints where the untested statements are, in the format go vet uses. The path in a profile names a Go package, so --old and --new take the root off the front, which is what leaves something an editor can open:

❯ prettycov misses --old=github.com/screwyprof/delegator --new=. --depth=max
pkg/httpkit/httpkit.go:62:2: 1 uncovered
pkg/logger/logger.go:22:16: 1 uncovered
pkg/logger/logger.go:44:26: 1 uncovered
…
❯ vim -q <(prettycov misses --old=$MODULE --new=. --depth=max)     # quickfix list
❯ prettycov misses --old=$MODULE --new=. --depth=max | reviewdog -f=golint -reporter=local

Vim's -q wants a filename rather than a pipe, so the process substitution, or redirect to a file first. -f=golint is reviewdog's name for file:line:col: message, not a claim about golint.

The reference has the rest.

The count matters: one untaken branch and a whole untested function look alike without it.

Leaving out what you never meant to test

--exclude drops generated code or a migrator before anything is totalled, and says what each pattern took, so a typo cannot pass for a clean run:

❯ prettycov report --exclude='/store/' --exclude='\.pb\.go$'
--exclude "/store/" left out 92 statements in 4 files
--exclude "\\.pb\\.go$" matched nothing
 github.com/screwyprof/delegator - 93.87
 ├ pkg - 93.33
 ├ scraper - 94.95
 └ web - 93.41

It reads the profile and nothing else. There is no source tree to find and no go.mod to parse, so it works on a CI artefact or on a repository you have not checked out.

Commands

command
reportdraw the packages and what they cover, one row each
missesprint where the uncovered statements are, as file:line:col
total [PATH]print only the number, for a Makefile or a badge
versionprint the version

prettycov --help lists them; prettycov <command> --help lists the flags that command takes. Flags belong to the command that reads them, so each listing is exactly what applies, and they are written after the command name.

Exit codes are 0, 1 when --fail-under was not met, and 2 when prettycov could not do what was asked. They are distinct so a CI step can tell a bad invocation from a failed gate.

Contributing

Go and make. Every tool the build needs is fetched at its pinned version by go run, never from your PATH. CONTRIBUTING.md has the gates and what a change is expected to carry.

More

docs/reference.md covers the rest: how the tree is built and why rows collapse, what --depth and --hide-covered do to a report, how total resolves a path, the file:line:col format and the editor settings that read it, and how --exclude accounts for what it removed.

License

MIT. See LICENSE.

Frequently Asked Questions

What is prettycov?

prettycov is a Testing library for the Go programming language. Draws a Go coverage profile as a package tree with a total on every row

How do I install prettycov?

Install prettycov with the Go module system using `go get screwyprof/prettycov`. Check the repository for the current installation instructions.

What category does prettycov belong to?

prettycov is listed under Testing, specifically Testing Frameworks.

← Back to Testing Frameworks