Go

How does test coverage work in Go? Explain covermode, -coverpkg, and coverage for integration tests.

Question 386MediumGo 1.22 to 1.25

The toolchain rewrites source to increment counters per basic block.

go test -coverprofile=cover.out ./...
go tool cover -func=cover.out      # per-function percentages
go tool cover -html=cover.out      # annotated source

go test -covermode=atomic -coverpkg=./... ./...
  • -covermode: set (was it run?), count (how many times), atomic (count, safe under concurrency — the default when -race is on).
  • -coverpkg=./...: by default coverage counts only the package under test; this counts code in other packages exercised by the tests too (e.g. handlers tested via an e2e package).

Integration coverage (Go 1.20+): build a real binary with coverage instrumentation, run it, and collect data:

go build -cover -o app ./cmd/app
GOCOVERDIR=./covdata ./app --run-scenario   # writes counter files on exit
go tool covdata percent -i=./covdata
go tool covdata textfmt -i=./covdata -o=cover.out

Interviewer is looking for: coverage is a tool for finding untested code, not a quality target — 100% line coverage says nothing about asserting the right behavior or edge cases. Error branches and concurrency paths are what usually lack coverage. Mutation testing or fuzzing find what coverage misses.

More on Performance, Profiling & Testing

All 38 Performance, Profiling & Testing questions