From 182d1316dd975f426451cee34ba2e3e0953e084f Mon Sep 17 00:00:00 2001 From: Russ Cox Date: Fri, 19 Sep 2014 13:51:06 -0400 Subject: cmd/go, testing: add TestMain support Fixes #8202. LGTM=r, bradfitz R=r, josharian, bradfitz CC=golang-codereviews https://golang.org/cl/148770043 --- src/testing/testing.go | 56 +++++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 51 insertions(+), 5 deletions(-) (limited to 'src/testing/testing.go') diff --git a/src/testing/testing.go b/src/testing/testing.go index 731762cb1d..21460b0ed4 100644 --- a/src/testing/testing.go +++ b/src/testing/testing.go @@ -117,6 +117,26 @@ // The entire test file is presented as the example when it contains a single // example function, at least one other function, type, variable, or constant // declaration, and no test or benchmark functions. +// +// Main +// +// It is sometimes necessary for a test program to do extra setup or teardown +// before or after testing. It is also sometimes necessary for a test to control +// which code runs on the main thread. To support these and other cases, +// if a test file contains a function: +// +// func TestMain(m *testing.M) +// +// then the generated test will call TestMain(m) instead of running the tests +// directly. TestMain runs in the main goroutine and can do whatever setup +// and teardown is necessary around a call to m.Run. It should then call +// os.Exit with the result of m.Run. +// +// The minimal implementation of TestMain is: +// +// func TestMain(m *testing.M) { os.Exit(m.Run()) } +// +// In effect, that is the implementation used when no TestMain is explicitly defined. package testing import ( @@ -431,23 +451,49 @@ func tRunner(t *T, test *InternalTest) { // An internal function but exported because it is cross-package; part of the implementation // of the "go test" command. func Main(matchString func(pat, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) { + os.Exit(MainStart(matchString, tests, benchmarks, examples).Run()) +} + +// M is a type passed to a TestMain function to run the actual tests. +type M struct { + matchString func(pat, str string) (bool, error) + tests []InternalTest + benchmarks []InternalBenchmark + examples []InternalExample +} + +// MainStart is meant for use by tests generated by 'go test'. +// It is not meant to be called directly and is not subject to the Go 1 compatibility document. +// It may change signature from release to release. +func MainStart(matchString func(pat, str string) (bool, error), tests []InternalTest, benchmarks []InternalBenchmark, examples []InternalExample) *M { + return &M{ + matchString: matchString, + tests: tests, + benchmarks: benchmarks, + examples: examples, + } +} + +// Run runs the tests. It returns an exit code to pass to os.Exit. +func (m *M) Run() int { flag.Parse() parseCpuList() before() startAlarm() - haveExamples = len(examples) > 0 - testOk := RunTests(matchString, tests) - exampleOk := RunExamples(matchString, examples) + haveExamples = len(m.examples) > 0 + testOk := RunTests(m.matchString, m.tests) + exampleOk := RunExamples(m.matchString, m.examples) stopAlarm() if !testOk || !exampleOk { fmt.Println("FAIL") after() - os.Exit(1) + return 1 } fmt.Println("PASS") - RunBenchmarks(matchString, benchmarks) + RunBenchmarks(m.matchString, m.benchmarks) after() + return 0 } func (t *T) report() { -- cgit v1.3 From 5edff3270479962ca67769947eb66adbe75e7fb4 Mon Sep 17 00:00:00 2001 From: Robert Griesemer Date: Wed, 1 Oct 2014 13:19:40 -0700 Subject: testing: clearer comment Fixes #8797. LGTM=r R=r CC=golang-codereviews https://golang.org/cl/146680043 --- src/testing/testing.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/testing/testing.go') diff --git a/src/testing/testing.go b/src/testing/testing.go index 21460b0ed4..f91d860a94 100644 --- a/src/testing/testing.go +++ b/src/testing/testing.go @@ -44,7 +44,7 @@ // } // // The benchmark function must run the target code b.N times. -// The benchmark package will vary b.N until the benchmark function lasts +// During benchark execution, b.N is adjusted until the benchmark function lasts // long enough to be timed reliably. The output // BenchmarkHello 10000000 282 ns/op // means that the loop ran 10000000 times at a speed of 282 ns per loop. -- cgit v1.3