Skip to content
Latchkey

go test -coverprofile: Coverage Reports in CI

go test -coverprofile=cover.out records statement coverage to a file that go tool cover turns into a percentage or HTML report.

Coverage in Go is built into go test. The CI flow is run with -coverprofile, then parse the total with go tool cover -func to enforce a threshold.

What it does

go test -coverprofile=<file> instruments the tested packages and writes a coverage profile. -covermode chooses how counts are recorded (set, count, atomic), and -coverpkg widens coverage to packages beyond the one under test. go tool cover then renders the profile.

Common usage

Terminal
go test -coverprofile=cover.out -covermode=atomic ./...
go tool cover -func=cover.out | tail -1        # total %
go tool cover -html=cover.out -o coverage.html
go test -coverpkg=./... -coverprofile=cover.out ./...

Flags

FlagWhat it does
-coverprofile <file>Write the coverage profile to a file
-covermode set|count|atomicCounting mode; atomic is required with -race
-coverpkg <pattern>Measure coverage for the listed packages
go tool cover -funcPrint per-function and total coverage
go tool cover -htmlRender an HTML coverage report

In CI

Use -covermode=atomic whenever you also pass -race, or counts are unsafe under concurrency. Cache the Go build and module caches to speed the instrumented run. Parse go tool cover -func=cover.out | tail -1 to grep the total percent and fail the job below your threshold.

Common errors in CI

"cannot use -coverprofile with multiple packages" appears only on old Go (<1.20); upgrade or run per-package and merge. "-coverpkg has no effect" usually means the pattern did not match the packages under test. "warning: no packages being tested depend on matches for pattern ..." from -coverpkg means a mismatched import path. With -race, forgetting -covermode=atomic can corrupt counts.

Related guides

Run this faster and cheaper on Latchkey managed runners. Start free →