Profiling test coverage
A great feature of the go test
tool is the metrics and visualizations that it provides for test coverage.
Go ahead and try running the tests in our project using the -cover
flag like so:
$ go test -cover ./... ok snippetbox.alexedwards.net/cmd/web 0.022s coverage: 46.1% of statements ? snippetbox.alexedwards.net/internal/assert [no test files] ok snippetbox.alexedwards.net/internal/models 1.081s coverage: 6.5% of statements ? snippetbox.alexedwards.net/internal/models/mocks [no test files] ? snippetbox.alexedwards.net/internal/validator [no test files] ? snippetbox.alexedwards.net/ui [no test files]
From the results here we can see that 46.1% of the statements in our cmd/web
package are executed during our tests, and for our internal/models
package the figure is 6.5%.
We can get a more detailed breakdown of test coverage by method and function by using the -coverprofile
flag like so:
$ go test -coverprofile=/tmp/profile.out ./...
This will execute your tests as normal and — if all your tests pass — it will then write a coverage profile to a specific location (in our case /tmp/profile.out
).
You can then view the coverage profile by using the go tool cover
command like so:
$ go tool cover -func=/tmp/profile.out snippetbox.alexedwards.net/cmd/web/handlers.go:15: home 0.0% snippetbox.alexedwards.net/cmd/web/handlers.go:31: snippetView 92.9% snippetbox.alexedwards.net/cmd/web/handlers.go:56: snippetCreate 0.0% snippetbox.alexedwards.net/cmd/web/handlers.go:82: snippetCreatePost 0.0% snippetbox.alexedwards.net/cmd/web/handlers.go:126: userSignup 100.0% snippetbox.alexedwards.net/cmd/web/handlers.go:132: userSignupPost 88.5% snippetbox.alexedwards.net/cmd/web/handlers.go:192: userLogin 0.0% snippetbox.alexedwards.net/cmd/web/handlers.go:198: userLoginPost 0.0% snippetbox.alexedwards.net/cmd/web/handlers.go:256: userLogoutPost 0.0% snippetbox.alexedwards.net/cmd/web/handlers.go:277: ping 100.0% snippetbox.alexedwards.net/cmd/web/helpers.go:17: serverError 0.0% snippetbox.alexedwards.net/cmd/web/helpers.go:27: clientError 100.0% snippetbox.alexedwards.net/cmd/web/helpers.go:34: notFound 100.0% snippetbox.alexedwards.net/cmd/web/helpers.go:38: newTemplateData 100.0% snippetbox.alexedwards.net/cmd/web/helpers.go:47: render 58.3% snippetbox.alexedwards.net/cmd/web/helpers.go:79: decodePostForm 50.0% snippetbox.alexedwards.net/cmd/web/helpers.go:108: isAuthenticated 75.0% snippetbox.alexedwards.net/cmd/web/main.go:31: main 0.0% snippetbox.alexedwards.net/cmd/web/main.go:95: openDB 0.0% snippetbox.alexedwards.net/cmd/web/middleware.go:11: secureHeaders 100.0% snippetbox.alexedwards.net/cmd/web/middleware.go:27: logRequest 100.0% snippetbox.alexedwards.net/cmd/web/middleware.go:35: recoverPanic 66.7% snippetbox.alexedwards.net/cmd/web/middleware.go:55: requireAuthentication 16.7% snippetbox.alexedwards.net/cmd/web/middleware.go:78: noSurf 100.0% snippetbox.alexedwards.net/cmd/web/middleware.go:90: authenticate 38.5% snippetbox.alexedwards.net/cmd/web/routes.go:12: routes 100.0% snippetbox.alexedwards.net/cmd/web/templates.go:23: humanDate 100.0% snippetbox.alexedwards.net/cmd/web/templates.go:40: newTemplateCache 83.3% snippetbox.alexedwards.net/internal/models/snippets.go:31: Insert 0.0% snippetbox.alexedwards.net/internal/models/snippets.go:61: Get 0.0% snippetbox.alexedwards.net/internal/models/snippets.go:98: Latest 0.0% snippetbox.alexedwards.net/internal/models/users.go:36: Insert 0.0% snippetbox.alexedwards.net/internal/models/users.go:68: Authenticate 0.0% snippetbox.alexedwards.net/internal/models/users.go:100: Exists 100.0% total: (statements) 38.1%
An alternative and more visual way to view the coverage profile is to use the -html
flag instead of -func
.
$ go tool cover -html=/tmp/profile.out
This will open a browser window containing a navigable and highlighted representation of your code, similar to this:

It’s easy to see exactly which statements get executed during your tests (colored green) and which are not (highlighted red).
You can take this a step further and use the -covermode=count
option when running go test
like so:
$ go test -covermode=count -coverprofile=/tmp/profile.out ./... $ go tool cover -html=/tmp/profile.out
Instead of just highlighting the statements in green and red, using -covermode=count
makes the coverage profile record the exact number of times that each statement is executed during the tests.
When viewed in the browser, statements which are executed more frequently are then shown in a more saturated shade of green, similar to this:
