It is possible to obtain coverage information when running a test in Go by using go test -cover ..., but this coverage doesn't extend to main programs which are invoked by the test. Is there some way of building a Go executable so that it is instrumented for coverage?
Related
I've been trying to generate code coverage for a vanilla Typescript (no react or any web frameworks) project on Webpack 5 using Cypress for unit testing. I'm not able to generate code coverage for it as if I'm failing to tell Cypress that it needs to use the source instrumented by nyc.
In order to come up with ideas on solving this, I need to know: how exactly nyc passes the instrumented source to test runners?
In this documentation, it mentioned using nyc to instrument the code but it doesn't really show how the instrumented code is going to be picked up by Cypress. Following the provided command line does not allow your cypress test to generate code.
I have tried instrumenting by nyc but it did not work. What worked was transpiling the typescript code and then instrumenting. Once it is instrumented you can deploy by the same way you currently do and then run your tests against it.
I know its possible to capture code coverage metrics when running unit tests. However, we would like to know what the coverage is when we run integrations tests (plural) against the binary itself, like:
go build
./mybin somefile1
./mybin somefile2
# ... test a bunch more files and input flags
Is it possible to do this? The binary can be built just for the purpose of testing, so any compile options as needed.
The Go coverage tool only works in conjunction with the testing package. But not all hope is lost.
If you can coerce your integration tests into the go testing framework, you should have all you need. This shouldn't be as hard as it sounds.
Basically:
Write a test file that executes your main() function in a go routine:
func TestMainApp(t *testing.T) {
go main()
// .. then start your integration tests
}
With your real app running from within a test, start your integration tests--likely with the help of exec.Cmd.
Gather your coverage stats.
Profit.
This article, Go coverage with external tests, from a year ago, outlines a similar approach.
I have a project like this:
app/
api/
foo.go
test_foo.go
src/
db/
bar.go
In foo.go, a call is made to a function in bar.go. However, when running the coverage report, it shows that 0 lines of bar.go are covered.
Is there a way to get coverage to include function call to other packages?
In my case, I do not want to make separate tests for db and for api, since all calls through db will always go through api, and it would be redundant to write two tests.
I'm running the coverage like this:
go clean -testcache
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
You need to include the coverpkg flag so:
go test -coverpkg=./... coverprofile=coverage.out ./...
Would calculate the coverage on all of your packages.
https://golang.org/cmd/go/#hdr-Testing_flags
Short answer. To see correct coverages run:
go test ./... -coverprofile=coverage.out -coverpkg=./...
go tool cover -html=coverage.out
And then see percentages in dropdown inside browser.
Longer answer with explanation why other ways not worked. So, I also have a project with api and store (in this question it is called db) packages, where store is used in api, and I have tests in api.
go test -cover ./...
Says that api is covered, store - "[no test files]".
When I run it like
go test -cover -coverpkg=./... ./...
It decreases coverage in api because now that number means how testcases in api package cover all the packages, which is not very useful number.
But there is a way to know how given package is covered by tests in all the packages (eg, how store is covered by tests from api and other places).
First, you generate coverage profile:
go test ./... -coverprofile=coverage.out -coverpkg=./...
Above command will still give you wrong percents in output, but it will create coverage.out file that will list all the lines in all packages covered by tests in all packages.
Then you could view this report in the browser with the command:
go tool cover -html=coverage.out
Then in the dropdown that allows you to select files to browse coverage for, you will get correct per file coverages.
I know its possible to capture code coverage metrics when running unit tests. However, we would like to know what the coverage is when we run integrations tests (plural) against the binary itself, like:
go build
./mybin somefile1
./mybin somefile2
# ... test a bunch more files and input flags
Is it possible to do this? The binary can be built just for the purpose of testing, so any compile options as needed.
The Go coverage tool only works in conjunction with the testing package. But not all hope is lost.
If you can coerce your integration tests into the go testing framework, you should have all you need. This shouldn't be as hard as it sounds.
Basically:
Write a test file that executes your main() function in a go routine:
func TestMainApp(t *testing.T) {
go main()
// .. then start your integration tests
}
With your real app running from within a test, start your integration tests--likely with the help of exec.Cmd.
Gather your coverage stats.
Profit.
This article, Go coverage with external tests, from a year ago, outlines a similar approach.
I've got some tests for my go project which are written in ruby/cucumber and I'm therefore unable to take advantage of the "go test"-based coverage tools to get coverage numbers for those tests (I also have unit tests and I'm happily generating coverage numbers for those).
Is there a way to create an instrumented build of go code such that I can generate coverage numbers for those non-go tests?
No. You would have to write a ruby/cucumber interpreter in GO, write/adapt a coverage testing framework and then integrate that with the go test framework.
Just rewrite the legacy ruby code in Go :P
NO, but you can run go test in a way that creates coverage html pages.
like this:
go test -v -coverprofile cover.out ./...
go tool cover -html=cover.out -o cover.html
open cover.html