diff options
Diffstat (limited to 'src/pkg/testing/testing.go')
-rw-r--r-- | src/pkg/testing/testing.go | 47 |
1 files changed, 40 insertions, 7 deletions
diff --git a/src/pkg/testing/testing.go b/src/pkg/testing/testing.go index 52dc166dd..8078ba7cc 100644 --- a/src/pkg/testing/testing.go +++ b/src/pkg/testing/testing.go @@ -8,9 +8,17 @@ // func TestXxx(*testing.T) // where Xxx can be any alphanumeric string (but the first letter must not be in // [a-z]) and serves to identify the test routine. -// These TestXxx routines should be declared within the package they are testing. // -// Tests and benchmarks may be skipped if not applicable like this: +// Within these functions, use the Error, Fail or related methods to signal failure. +// +// To write a new test suite, create a file whose name ends _test.go that +// contains the TestXxx functions as described here. Put the file in the same +// package as the one being tested. The file will be excluded from regular +// package builds but will be included when the ``go test'' command is run. +// For more detail, run ``go help test'' and ``go help testflag''. +// +// Tests and benchmarks may be skipped if not applicable with a call to +// the Skip method of *T and *B: // func TestTimeConsuming(t *testing.T) { // if testing.Short() { // t.Skip("skipping test in short mode.") @@ -43,6 +51,7 @@ // // If a benchmark needs some expensive setup before running, the timer // may be reset: +// // func BenchmarkBigLen(b *testing.B) { // big := NewBig() // b.ResetTimer() @@ -51,6 +60,21 @@ // } // } // +// If a benchmark needs to test performance in a parallel setting, it may use +// the RunParallel helper function; such benchmarks are intended to be used with +// the go test -cpu flag: +// +// func BenchmarkTemplateParallel(b *testing.B) { +// templ := template.Must(template.New("test").Parse("Hello, {{.}}!")) +// b.RunParallel(func(pb *testing.PB) { +// var buf bytes.Buffer +// for pb.Next() { +// buf.Reset() +// templ.Execute(&buf, "World") +// } +// }) +// } +// // Examples // // The package also runs and verifies example code. Example functions may @@ -143,10 +167,11 @@ var ( // common holds the elements common between T and B and // captures common methods such as Errorf. type common struct { - mu sync.RWMutex // guards output and failed - output []byte // Output generated by test or benchmark. - failed bool // Test or benchmark has failed. - skipped bool // Test of benchmark has been skipped. + mu sync.RWMutex // guards output and failed + output []byte // Output generated by test or benchmark. + failed bool // Test or benchmark has failed. + skipped bool // Test of benchmark has been skipped. + finished bool start time.Time // Time test or benchmark started duration time.Duration @@ -275,6 +300,7 @@ func (c *common) FailNow() { // it would run on a test failure. Because we send on c.signal during // a top-of-stack deferred function now, we know that the send // only happens after any other stacked defers have completed. + c.finished = true runtime.Goexit() } @@ -338,6 +364,7 @@ func (c *common) Skipf(format string, args ...interface{}) { // those other goroutines. func (c *common) SkipNow() { c.skip() + c.finished = true runtime.Goexit() } @@ -379,7 +406,11 @@ func tRunner(t *T, test *InternalTest) { defer func() { t.duration = time.Now().Sub(t.start) // If the test panicked, print any test output before dying. - if err := recover(); err != nil { + err := recover() + if !t.finished && err == nil { + err = fmt.Errorf("test executed panic(nil) or runtime.Goexit") + } + if err != nil { t.Fail() t.report() panic(err) @@ -389,6 +420,7 @@ func tRunner(t *T, test *InternalTest) { t.start = time.Now() test.F(t) + t.finished = true } // An internal function but exported because it is cross-package; part of the implementation @@ -405,6 +437,7 @@ func Main(matchString func(pat, str string) (bool, error), tests []InternalTest, stopAlarm() if !testOk || !exampleOk { fmt.Println("FAIL") + after() os.Exit(1) } fmt.Println("PASS") |