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.
Related
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 Go project that uses modules. The module contains many packages, which are nested.
When I let Go figure out the package structure by passing ./... to go test it runs the tests in parallel (the default behaviour).
Testing a single package with the -failfast flag works, it stops at the first failure, however what I'd like to achieve is to use -failfast across all the packages combined (for increased CI/CD throughput). When the first test in one of the packages that are tested in parallel by a single go test ./... invocation fails, I'd like to stop the whole test suite.
Is this even possible with the current version of the go testing utility? If not, is there perhaps a plan to implement such thing in the future?
I did not find a solution that would enable me to do this in parallel yet, however one thing that I thought of is to combine something like go test -failfast, go list ./... and xargs and run tests in a sequence (not parallely). I'd check the output of the last tested package and stop everything on first failure. This doesn't sound that good though and will probably be quite a bit slower.
So yeah, are there any existing solutions or approaches that I haven't found/thought of?
Thanks!
go version go1.12 darwin/amd64
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.
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?
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