In your go project you can get test coverage by running
go test ./... -coverprofile=cover.out
go tool cover -cover=cover.outThis will produce following output:
github.com/yb172/coverage-lines/collider/starter.go:8: Collide 100.0%
github.com/yb172/coverage-lines/collider/starter.go:18: checkMass 100.0%
github.com/yb172/coverage-lines/loader/yaml.go:12: LoadFromYaml 100.0%
total: (statements) 100.0%
If you have multiple projects and all of them are writtenn in Go you can also get total coverage by running the same commands on directory where all projects are contained.
However if you have some projects not in Go that won't work.
Instead we need to get total LOC and LOC under test for our Go and non-Go projects and covered/all would be our coverage.
Straightforward approach would be to use LOC counter tool such as gocloc. Let's run it on our example program and see what it will produce:
gocloc --by-file --not-match-d=vendor --include-lang=go .It will produce following result:
----------------------------------------------------------------------------
File files blank comment code
----------------------------------------------------------------------------
collider/starter_test.go 9 0 54
loader/yaml_test.go 7 0 35
collider/starter.go 4 1 24
loader/yaml.go 3 1 18
run-collider.go 3 0 18
collider/structs.go 1 1 5
----------------------------------------------------------------------------
TOTAL 6 27 3 154
----------------------------------------------------------------------------
First obvious problem is that *_test.go are also included. Let's calculate what is LOC count without tests:
24 (starter.go) + 18 (yaml.go) + 5 (structs.go) = 47
I also excluded run-collider.go since it wasn't included in cover.out.
Now let's manually count what is the number of lines covered by tests. Html report for go coverage would help us:
go tool cover -html=cover.outResults are (if count opening curly brace { also a line):
18 (starter.go) + 10 (yaml.go) = 28
So according to our straightforward approach our test coverage is:
28 / 47 = 59.6%
Not great. Why is it so? Because gocloc counts lines of code and import as well as type Particle struct { are also considered as lines of code.
So to correctly calculate coverage we need another approach.
That would be great if there would be a special flag in go tool cover that will output how many lines are covered and total lines. Unfortunately I haven't found such flag.
Good news is that all the information we need is already calculated in go tool cover: github.com/golang/tools/blob/master/cmd/cover/func.go#L57. We just need to print covered and total instead of it's ratio. That is what is done in "coverage-lines". Let's install and run it:
coverage-lines cover.outResult is
20 20
Interesting: there are actually 20 lines to test according to the profile, not 28 that I got by counting green lines. Apparently { as well as } are not counted as a line (which makes sense).