First of all, running tests should be done via the go test command.
Certain types and functions exported in the testing package are for the testing framework, not for you. Quoting from testing.RunTests():
RunTests is an internal function but exported because it is cross-package; it is part of the implementation of the "go test" command.
It "had" to be exported because it predates "internal" packages.
There. You've been warned.
If you still want to do it, call testing.Main() instead of testing.RunTests().
For example:
func TestGood(t *testing.T) {
}
func TestBad(t *testing.T) {
t.Error("This is a mocked failed test")
}
func main() {
testing.Main(
nil,
[]testing.InternalTest{
{"Good", TestGood},
{"Bad", TestBad},
},
nil, nil,
)
}
Which will output (try it on the Go Playground):
--- FAIL: Bad (0.00s)
prog.go:11: This is a mocked failed test
FAIL
If you want to capture the success of the testing, use the "newer" testing.MainStart() function.
First we need a helper type (which implements an unexported interface):
type testDeps struct{}
func (td testDeps) MatchString(pat, str string) (bool, error) { return true, nil }
func (td testDeps) StartCPUProfile(w io.Writer) error { return nil }
func (td testDeps) StopCPUProfile() {}
func (td testDeps) WriteProfileTo(string, io.Writer, int) error { return nil }
func (td testDeps) ImportPath() string { return "" }
func (td testDeps) StartTestLog(io.Writer) {}
func (td testDeps) StopTestLog() error { return nil }
func (td testDeps) SetPanicOnExit0(bool) {}
And now using it:
m := testing.MainStart(testDeps{},
[]testing.InternalTest{
{"Good", TestGood},
{"Bad", TestBad},
},
nil, nil,
)
result := m.Run()
fmt.Println(result)
Which outputs (try it on the Go Playground):
--- FAIL: Bad (0.00s)
prog.go:13: This is a mocked failed test
FAIL
1
If all tests pass, result will be 0.