如何从golang中的测试超时恐慌中恢复?
main.go:
package main
import "fmt"
func main() {
fmt.Println("main")
}
main_test.go:
package main
import (
"fmt"
"os"
"testing"
"time"
)
func TestMain(m *testing.M) {
defer PanicHandle() // this doesn't work
retCode := m.Run()
fmt.Println("retCode", retCode)
}
func PanicHandle() {
if r := recover(); r != nil {
fmt.Println("panic handled")
os.Exit(1)
}
}
func Test1(t *testing.T) {
defer PanicHandle()
fmt.Println("test1")
time.Sleep(time.Second)
}
使用命令运行:
go test -c -o test && ./test -test.timeout 1s
我在recover()
和TestMain
中使用Test1
。但恐慌panic: test timed out after 1s
无论如何都没有恢复。
为了简化代码,我重构了它:
package main
import (
"fmt"
"os"
"testing"
"time"
)
func TestMain(m *testing.M) {
defer func() {
if r := recover(); r != nil {
fmt.Println("panic handled")
os.Exit(1)
}
}()
retCode := m.Run()
fmt.Println("retCode", retCode)
}
func Test1(t *testing.T) {
defer func() {
if r := recover(); r != nil {
fmt.Println("panic handled")
os.Exit(1)
}
}()
fmt.Println("test1")
time.Sleep(time.Second)
panic("panic in test1")
}
通常的恐慌处理: 去测试-v -timeout 2 s
=== RUN Test1
test1
panic handled
exit status 1
但超时恐慌不是: 去测试-v -timeout 1 s
=== RUN Test1
test1
panic: test timed out after 1s
goroutine 21 [running]:
panic(0xe5520, 0xc42008e490)
/usr/local/go/src/runtime/panic.go:500 +0x1a1
testing.startAlarm.func1()
/usr/local/go/src/testing/testing.go:918 +0x10b
created by time.goFunc
/usr/local/go/src/time/sleep.go:154 +0x44
goroutine 1 [chan receive]:
testing.(*T).Run(0xc42009a0c0, 0x10cf65, 0x5, 0x11b928, 0x58135)
/usr/local/go/src/testing/testing.go:647 +0x316
testing.RunTests.func1(0xc42009a0c0)
/usr/local/go/src/testing/testing.go:793 +0x6d
testing.tRunner(0xc42009a0c0, 0xc42003fdb0)
/usr/local/go/src/testing/testing.go:610 +0x81
testing.RunTests(0x11b938, 0x191230, 0x1, 0x1, 0x27be3)
/usr/local/go/src/testing/testing.go:799 +0x2f5
testing.(*M).Run(0xc42003fee8, 0x11b930)
/usr/local/go/src/testing/testing.go:743 +0x85
github.com/ypapax/deferPanic.TestMain(0xc42003fee8)