I want to write an integration test which tests writing and reading data to and from a database. In order to do this, I need my first test function to connect and prepare a test database; and if that is a success, let the other tests run, which will then be doing queries on it.
So I implemented a TestMain(m *testing.M)
which creates a database and runs migrations on it, and if there's no errors, I run m.Run()
.
But it doesn't have any m.Print
or m.Fatal
methods like testing.T
does. And if I try to log something with log.Print()
, it doesn't get output (probably because no testing could have been properly marked as failing).
And the reason why I don't like the creation of the database with a regular test function, is because a regular test of course cannot stop other tests from running, so all my other tests from that file will run and plague the output messages, since they will all fail.
So how do I log something out from TestMain? My TestMain can still fail in multiple ways, and i would like to see in the output what it was.
Example to show TestMain
's output not being displayed:
$ ls
go.mod main_test.go
$ cat go.mod
module App
go 1.16
$ cat main_test.go
package main
import (
"testing"
"log"
)
func TestMain(m *testing.M) {
log.Print("hello")
}
$ go test ./.
ok App 0.147s
$
You need the
-v
flag:Note:
.
is equivalent to./.
If you want to run tests on all sub-directories use
./...
like so:Why is this? Since you are running tests in what's call package list mode (i.e.
./.
) - from the docs ingo help test
:This is the behavior you have noted. Reading further:
Note:
go test
alone (i.e. no package list) will allow output logging fromTestMain
likelog.Print
.EDIT here's how I typically do pre-flight setup for my tests:
if any of the prep fails, then
log.Fatal
ensures the reason is logged & the program terminates.