Go: Wrong coverage when there is no tests for a package - go

I have a Go project with the following structure:
foo/foo.go
foo/foo_test.go
main.go
As you notice, there is no test for main.go.
I collect the coverage report using the following command:
go test ./foo ./ -coverprofile=coverage.txt -covermode=atomic
Here ./foo and ./ show where to look for packages.
Problem: I send the coverage report to codecov.io which shows that my code is 100% covered with tests. But this is not true as my main.go has no tests at all.
It seems like the system only counts those packages that explicitly specify test files.
Question: How to fix the coverage report in the way that it will count information about untested packages?
Note: You can find my project on GitHub and the real statistic is here. The project has a different structure, but the issue persists (wrong coverage).

The -coverpkg flag may be used to specify the packages that are used as the basis of coverage analyis.
Quoting from Command go: Testing flags:
-coverpkg pattern1,pattern2,pattern3
Apply coverage analysis in each test to packages matching the patterns.
The default is for each test to analyze only the package being tested.
See 'go help packages' for a description of package patterns.
Sets -cover.
So in your specific example this will do it:
go test -coverpkg=.,./foo -coverprofile=coverage.txt -covermode=atomic . ./foo
To apply it for a complete module / project, you may use:
go test -coverpkg=./... -coverprofile=coverage.txt -covermode=atomic ./...
Another option is to place an "empty" test file into the folders of packages that do not currently have a test file. That way they will be naturally included in default coverage analysis, but obviously nothing will be covered from them.
See related discussion on github:
cmd/go: go test -cover & go test -coverprofile should always output a coverage #24570

try this one:
go test -coverpkg=./... -race -coverprofile=coverage.txt -covermode=atomic ./..

Related

When executing go tests is including main.go and I want to ignore it

When executing the following command in my go project:
go test ./... -coverprofile cover.out
I get the test coverage, but before I refactored the code, I did not see any reference to in the code coverage regarding the file main.go (which I wanted), now, I just refactor the code by creating some packages, but main.go remaining in the root folder, and now the exact same command includes main.go for the code coverage, which I don't want. Any idea what's the reason of it?

Go Test Coverage, over different packages [duplicate]

This question already has answers here:
No test coverage when tests are in a different package
(2 answers)
Go Coverage not including functions in other package
(2 answers)
Closed 2 years ago.
I have been writing an rest service I have the following structure
/controllers
/domain/dao
/services
after writing a lot of tests for each individual package with mocks for each stage, I thought it would be quicker to just write tests against the controller and mock the database, so in that I know the /domain/dao layer is being called.
My problem now is when I run code coverage I do not get the coverage for my /service or the /domain/dao even though I know the code is being called
Any ideas on how to get my code coverage on all files?
You can try the flag -coverpkg
go test --cover -coverpkg=./services ./... -coverprofile=cover.out
To check all the packages in the folder /services as well, you can try:
go test --cover -coverpkg=./services/... ./... -coverprofile=cover.out
Just a side note - I usually add -covermode=count
go test --cover -covermode=count -coverpkg=./services/... ./... -coverprofile=cover.out
Then, you can use go tool to see it as html:
go tool cover -html=cover.out

Running benchmarks of subfolders from the project root

I have a project with a binary which entrypoint is located in ./cmd/<my-project>/main.go.
I've added a benchmark in ./cmd/<my-project>/main_test.go.
Now I want to execute this benchmark from the repository root.
I've tried to execute something like go test -bench=./cmd/<my-project>/main in various alternations (like for example go test -bench=./cmd/<my-project>/main_test.go or go test -bench=./cmd/<my-project>) but I couldn't get it to work.
The error I always get is:
can't load package: package github.com/<username>/<my-project>: no Go files in /home/<user>/go/src/github.com/<username>/<my-project>
and it's true, I have no *.go files in my project root.
All I came up with is changing into the directory first and run the benchmark with `go test -bench=.
However, as my program depends on the current working directory and the result is heavily depending on that it would be great to be able to execute it in another directory than the cmd/<my-project> one. (If this is good or not isn't part of the question :))
Update after the first comment:
I get it to run with go test -bench=. /cmd/<my-project> but the benchmark get's executed as if it would be run in the ./cmd/<my-project> directory.
I've noticed similiar behaviour in 'normal tests' - but that wasn't a problem for me at any time.
So, my program does scan the current directory for files directories depending on the current working directory, this results in only two files found (main.go and main_test.go) where the benchmark isn't really helpful.
So to run the benchmarks:
go test -bench=. ./cmd/<my-project>
However, you are wanting to control the working directory, so really you want to run it from somewhere else. What you are looking for is the -c flag. It will create a binary instead of running the tests. You can then run the binary (and therefore your tests and benchmarks) where you want.
go test -c ./cmd/my_proj
my_proj.test -test.bench=.
NOTE: Flags are prefixed with test. when you compile the tests.

"go test" reports incorrect statement coverage

I have a package with only two Go file: one defines the main function and the other is for the tests.
Now assume that I have cd into this package and run the following command:
$ go test -cover
PASS
coverage: 41.8% of statements
ok github.com/suzaku/dummage 0.010s
As you can see, this works correctly.
But I want to generate a HTML report, so after some googling I use the following command:
$ go test -run=Coverage -coverprofile=c.out github.com/suzaku/dummage
ok github.com/suzaku/dummage 0.010s coverage: 1.8% of statements
Note that this time the coverage drops to 1.8%.
What can I do to fix this?
Are you sure you need that -run=Coverage flag in your go test? This means it will only run tests that match Coverage. If you just want to generate a cover profile for that tests, run go test -coverprofile c.out github.com/suzaku/dummage. Then you may run go tool cover -html c.out to see the HTML report.
If you added -run=Coverage on purpose, then it's expected behavior - the amount of code that runs during -run=Coverage is much less than while running all tests, and the test coverage is calculated for the entire package.

How do I set up a Ginkgo test suite?

I have inherited a Go project that consists of a lot of common files, a library of sorts, two executables, and theoretically a test suite. The test suite is being written after the fact. But I dislike the only way I've found of setting up is rather unpalatable
I'm using Ginkgo, and this is my starting directory structure
component1/component1.go
component2/component2.go
cmd1/cmd1.go
cmd2/cmd2.go
project_suite_test.go
component1_test.go
Each cmd?.go file will be compiled into a separate executable.
What I would like is a multi-file test suite, usually one file per component. Where do I put the files so that go test will find and run all of them, without leaving them here in the root of the project?
ginkgo init and ginkgo bootstrap will set up your tests. ginkgo -r will run all your tests recursively.
Reason:
Ginkgo command will only work if you have actually bootstrap your project via ginkgo.
Options:
To use that you have to go to your test dir in terminal and run
ginkgo init : To Initialise project:
ginkgo bootstrap : This will generate new file with test suite config
ginkgo or ginkgo test : this will now be able to run tests based on your new generated file because that's what it is trying to search.
Alternatively:
If you like to keep your tests in a sub-folder, say test, then running
go test ./...
will attempt to run tests in every folder, even those that do not contain any test, thus having a ? in the subsequent report for non-test folders.
Running
go test ./.../test
instead will target only your test folders, thus having a clean report focused on your tests folders only.
you can alternatively use 'go run $(ls *.go)' to run all the files in a given folder.
Notice you have regular expression within () braces.
In-case you want to run test in different path update path as per your desired dir in the regular expression
You can use go test ./... in the root and it will go into child folders and execute the tests:
component1/component1.go
component1/component1_test.go
component2/component2.go
component2/component2_test.go
cmd1/cmd1.go
cmd1/cmd1_test.go
cmd2/cmd2.go
cmd2/cmd2_test.go

Resources