-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Closed
Labels
FrozenDueToAgeProposalProposal-Acceptedearly-in-cycleA change that should be done early in the 3 month dev cycle.A change that should be done early in the 3 month dev cycle.
Milestone
Description
When a test panics in a table-driven test, it is difficult to tell which case caused the failure. For example:
func Test(t *testing.T) {
for _, test := range []int{1, 2, 0, 3} {
t.Run(fmt.Sprintf("%v", test), func(t *testing.T) {
_ = 1 / test
})
}
}panic: runtime error: integer divide by zero [recovered]
panic: runtime error: integer divide by zero
goroutine 8 [running]:
testing.tRunner.func1(0xc0000ac400)
/usr/lib/google-golang/src/testing/testing.go:830 +0x388
panic(0x511aa0, 0x623f00)
/usr/lib/google-golang/src/runtime/panic.go:522 +0x1b5
_/usr/local/google/home/dneil/src/testpanic_test.Test.func1(0xc0000ac400)
/usr/local/google/home/dneil/src/testpanic/panic_test.go:11 +0x24
testing.tRunner(0xc0000ac400, 0xc00005c490)
/usr/lib/google-golang/src/testing/testing.go:865 +0xc0
created by testing.(*T).Run
/usr/lib/google-golang/src/testing/testing.go:916 +0x357
FAIL _/usr/local/google/home/dneil/src/testpanic 0.018s
We know that testpanic_test.Test panicked, but we don't know which test case is to blame. You can get a much more useful error by manually recovering the panic and converting it to a t.Fatal:
func Test(t *testing.T) {
for _, test := range []int{1, 2, 0, 3} {
t.Run(fmt.Sprintf("%v", test), func(t *testing.T) {
defer func() {
if err := recover(); err != nil {
t.Error(string(debug.Stack()))
t.Fatal(err)
}
}()
_ = 1 / test
})
}
}--- FAIL: Test (0.00s)
--- FAIL: Test/0 (0.00s)
panic_test.go:14: runtime error: integer divide by zero
goroutine 8 [running]:
runtime/debug.Stack(0xc000046670, 0x512aa0, 0x625f00)
/usr/lib/google-golang/src/runtime/debug/stack.go:24 +0x9d
_/usr/local/google/home/dneil/src/testpanic_test.Test.func1.1(0xc0000ac400)
/usr/local/google/home/dneil/src/testpanic/panic_test.go:14 +0x57
panic(0x512aa0, 0x625f00)
/usr/lib/google-golang/src/runtime/panic.go:522 +0x1b5
_/usr/local/google/home/dneil/src/testpanic_test.Test.func1(0xc0000ac400)
/usr/local/google/home/dneil/src/testpanic/panic_test.go:17 +0x7c
testing.tRunner(0xc0000ac400, 0xc00005c490)
/usr/lib/google-golang/src/testing/testing.go:865 +0xc0
created by testing.(*T).Run
/usr/lib/google-golang/src/testing/testing.go:916 +0x35a
FAIL
FAIL _/usr/local/google/home/dneil/src/testpanic 0.016s
I propose that the testing package do something like that automatically. Perhaps rather than converting the panic to a t.Fatal it should print the failing test name and continue panicking; the important point is to provide information about which test case triggered the panic.
This doesn't help with panics in goroutines started by a test, of course.
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
FrozenDueToAgeProposalProposal-Acceptedearly-in-cycleA change that should be done early in the 3 month dev cycle.A change that should be done early in the 3 month dev cycle.