summaryrefslogtreecommitdiff
path: root/src/pkg/testing/testing.go
diff options
context:
space:
mode:
Diffstat (limited to 'src/pkg/testing/testing.go')
-rw-r--r--src/pkg/testing/testing.go47
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")