Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to generate coverage for multiple packages using go test in custom folders?

We have following project structure:

├── Makefile
├── ...
├── src
│   ├── app
│   │   ├── main.go
│   │   ├── models
│   │       ├── ...
│   │       └── dao.go
│   │   ├── ...
│   │   └── controllers
│   │       ├── ...
│   │       └── pingController.go
│   └── test
│       ├── all_test.go
│       ├── ...
│       └── controllers_test.go
└── vendor
    └── src
        ├── github.com
        ├── golang.org
        └── gopkg.in

I want to measure coverage of packages in src/app by tests in src/test. And currently generating coverage profile by running custom script that runs coverage for each package in app and then merges all coverage profiles into one file. Recently I heard that in go1.10 we are able to generate coverage for multiple packages.

So I tried to replace that script with oneliner, and tried running

GOPATH=${PROJECT_DIR}:${PROJECT_DIR}/vendor go test -covermode count -coverprofile cover.out -coverpkg all ./src/test/...

It gives me "ok test 0.475s coverage: 0.0% of statements in all"

When I do

cd src/test/
GOPATH=${PROJECT_DIR}:${PROJECT_DIR}/vendor go test -covermode count -coverprofile cover.out -coverpkg all

Logs show that specs are runned and tests are successfull, but still I have "coverage: 0.0% of statements in all" and empty cover.out.

What am I missing to properly compute coverage of packages in app by tests in test?

like image 635
Bunyk Avatar asked Mar 26 '18 10:03

Bunyk


2 Answers

You can't with the current state of go test but you can always use third party scripts.

https://github.com/grosser/go-testcov

like image 116
krain143 Avatar answered Sep 29 '22 18:09

krain143


Short answer:

go test -race -coverprofile=coverage.txt -covermode=atomic ./...  # Run all the tests with the race detector enabled
go test -bench=. -benchmem ./... # Run all the benchmark for 3s and print memory information

In order to create a test for a Go code, you have to create a file (in the same folder of the root code) that have the same name of the code, and append "_test" to the name. The package have to be the same too.

So, if I have a GO Code called strings.go, the relative test suite have to be named: strings_test.go.

After that, you have to create a method that have in input the t *testing.T struct, and the name of the method have to start with Test or Benchmark word.

So, if the strings.go contains a method called "IsUpper", the related test-case is a method called TestIsUpper(t *testing.T).
If you need the Benchmark, than you need to substitute the Test word with Benchmark, so the name of the method will be BenchmarkIsUpper, and the struct that the method take in input is b *testing.B.

You can have a look at the following link in order to see the tree-structure necessary for execute the test in GO: https://github.com/alessiosavi/GoGPUtils.

There you can find Benchmark and TestCase.

Here an example of tree-struct

├── string
│   ├── stringutils.go
│   └── stringutils_test.go
like image 37
alessiosavi Avatar answered Sep 29 '22 16:09

alessiosavi