diff options
| author | Damien Neil <dneil@google.com> | 2019-05-30 09:46:56 -0700 |
|---|---|---|
| committer | Damien Neil <dneil@google.com> | 2019-10-30 20:46:44 +0000 |
| commit | 81a74b4e8d4a1740529bb951eaa9569d429e4c0f (patch) | |
| tree | c54e366689ebc60a29901197517c4e1f6b3f5c9c /src/testing/panic_test.go | |
| parent | cd18da451faedc4218a5fd0e38f9b3d13aa5da01 (diff) | |
| download | go-81a74b4e8d4a1740529bb951eaa9569d429e4c0f.tar.xz | |
testing: provide additional information when test funcs panic
Flush the output log up to the root when a test panics. Prior to
this change, only the current test's output log was flushed to its
parent, resulting in no output when a subtest panics.
For the following test function:
func Test(t *testing.T) {
for i, test := range []int{1, 0, 2} {
t.Run(fmt.Sprintf("%v/%v", i, test), func(t *testing.T) {
_ = 1 / test
})
}
}
Output before this change:
panic: runtime error: integer divide by zero [recovered]
panic: runtime error: integer divide by zero
(stack trace follows)
Output after this change:
--- FAIL: Test (0.00s)
--- FAIL: Test/1/0 (0.00s)
panic: runtime error: integer divide by zero [recovered]
(stack trace follows)
Fixes #32121
Change-Id: Ifee07ccc005f0493a902190a8be734943123b6b7
Reviewed-on: https://go-review.googlesource.com/c/go/+/179599
Run-TryBot: Damien Neil <dneil@google.com>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/testing/panic_test.go')
| -rw-r--r-- | src/testing/panic_test.go | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/src/testing/panic_test.go b/src/testing/panic_test.go new file mode 100644 index 0000000000..3491510b81 --- /dev/null +++ b/src/testing/panic_test.go @@ -0,0 +1,83 @@ +// Copyright 2019 The Go Authors. All rights reserved. +// Use of this source code is governed by a BSD-style +// license that can be found in the LICENSE file. + +package testing_test + +import ( + "flag" + "fmt" + "internal/testenv" + "os" + "os/exec" + "regexp" + "strings" + "testing" +) + +var testPanicTest = flag.String("test_panic_test", "", "TestPanic: indicates which test should panic") + +func TestPanic(t *testing.T) { + testenv.MustHaveExec(t) + + testCases := []struct { + desc string + flags []string + want string + }{{ + desc: "root test panics", + flags: []string{"-test_panic_test=TestPanicHelper"}, + want: ` +--- FAIL: TestPanicHelper (N.NNs) + panic_test.go:NNN: TestPanicHelper +`, + }, { + desc: "subtest panics", + flags: []string{"-test_panic_test=TestPanicHelper/1"}, + want: ` +--- FAIL: TestPanicHelper (N.NNs) + panic_test.go:NNN: TestPanicHelper + --- FAIL: TestPanicHelper/1 (N.NNs) + panic_test.go:NNN: TestPanicHelper/1 +`, + }} + for _, tc := range testCases { + t.Run(tc.desc, func(t *testing.T) { + cmd := exec.Command(os.Args[0], "-test.run=TestPanicHelper") + cmd.Args = append(cmd.Args, tc.flags...) + cmd.Env = append(os.Environ(), "GO_WANT_HELPER_PROCESS=1") + b, _ := cmd.CombinedOutput() + got := string(b) + want := strings.TrimSpace(tc.want) + re := makeRegexp(want) + if ok, err := regexp.MatchString(re, got); !ok || err != nil { + t.Errorf("output:\ngot:\n%s\nwant:\n%s", got, want) + } + }) + } +} + +func makeRegexp(s string) string { + s = regexp.QuoteMeta(s) + s = strings.ReplaceAll(s, ":NNN:", `:\d+:`) + s = strings.ReplaceAll(s, "N\\.NNs", `\d*\.\d*s`) + return s +} + +func TestPanicHelper(t *testing.T) { + if os.Getenv("GO_WANT_HELPER_PROCESS") != "1" { + return + } + t.Log(t.Name()) + if t.Name() == *testPanicTest { + panic("panic") + } + for i := 0; i < 3; i++ { + t.Run(fmt.Sprintf("%v", i), func(t *testing.T) { + t.Log(t.Name()) + if t.Name() == *testPanicTest { + panic("panic") + } + }) + } +} |
