I have a function main()
in main.go that does the job and all other functions are below it (I did not include them here). So, when I write tests for all funcs
that are included in main
, I can test them. But the code coverage is low because it shows that I did not cover code from my main
func.
I know that there is a TestMain
func in the testing library that should do the job, but I just cannot get how to get it to work so that the tests cover func main()
.
Below is my main()
func which is not covered by tests...
func main() {
c, err := getConfig()
if err != nil {
log.Fatal(err)
}
slideshows, err := getSlideshows(c)
if err != nil {
log.Fatal(err)
}
displaySlideshows(slideshows)
}
Also, I did not find much about it on the internet, so, if this is a stupid question, please, explain to me why this is such a dum problem and where I should search for solutions!
I will appreciate any help!
You can check out "Go coverage with external tests", by Filippo Valsorda:
We create a dummy test that executes
main()
, we put it behind a build tag, compile a binary withgo test -c -cover
and then run only that test instead of running the regular binary.Here's what the
rrdns_test.go
file looks like:
Note the empty line between the build tag and package
:
// +build testrunmain package main import "testing" func TestRunMain(t *testing.T) { main() }
We compile the binary like this:
$ go test -coverpkg="rrdns/..." -c -tags testrunmain rrdns
And then when we want to collect coverage information, we execute this instead of
./rrdns
(and run our test battery as usual):$ ./rrdns.test -test.run "^TestRunMain$" -test.coverprofile=system.out
You must return from
main()
cleanly for the profile to be written to disk; inRRDNS
we do that by catchingSIGINT
. You can still use command line arguments and standard input normally, just note that you will get two lines of extra output from the test framework.
This is similar to this answer which proposes:
func main() { os.Exit(doFunc()); }