go test - 模糊测试

ddatsh

dev #go go-test

go fuzzing 通过持续给程序不同的输入来自动化测试,并通过分析代码覆盖率来智能的寻找失败的 case。这种方法可以尽可能的寻找到一些边缘 case,发现平时很难发现的问题

1.18 整合进标准库

模糊测试会监测程序运行过程中是否出现 panic、断言失败、无限循环等异常情况

// div.go
func Div(a, b int) int {
	return a / b
}
go test -fuzz .
// div_test.go
import "testing"

func FuzzDiv(f *testing.F) {
    f.Fuzz(func(t *testing.T, a, b int) {
       Div(a, b)
    })
}
fuzz: elapsed: 0s, gathering baseline coverage: 0/1 completed
fuzz: elapsed: 0s, gathering baseline coverage: 1/1 completed, now fuzzing with 8 workers
fuzz: elapsed: 0s, execs: 134 (1846/sec), new interesting: 0 (total: 1)
--- FAIL: FuzzDiv (0.07s)
    --- FAIL: FuzzDiv (0.00s)
        testing.go:1504: panic: runtime error: integer divide by zero
            goroutine 147 [running]:
            runtime/debug.Stack()
                runtime/debug/stack.go:24 +0x9b
            testing.tRunner.func1()
                testing/testing.go:1504 +0x1ee
            panic({0x662a20?, 0x7f9240?})
                runtime/panic.go:914 +0x21f
            example.Div(...)
                example/div.go:4
            example.FuzzDiv.func1(0x0?, 0x0?, 0x0?)
                example/div_test.go:7 +0x2c
            reflect.Value.call({0x65ebe0?, 0x6a5738?, 0x693260?}, {0x693dc7, 0x4}, {0xc000167560, 0x3, 0x30?})
                reflect/value.go:596 +0xce7
            reflect.Value.Call({0x65ebe0?, 0x6a5738?, 0x7eabc0?}, {0xc000167560?, 0x693260?, 0x57614d?})
                reflect/value.go:380 +0xb9
            testing.(*F).Fuzz.func1.1(0x4367c0?)
                testing/fuzz.go:335 +0x347
            testing.tRunner(0xc00017dd40, 0xc000177050)
                testing/testing.go:1595 +0xff
            created by testing.(*F).Fuzz.func1 in goroutine 6
                testing/fuzz.go:322 +0x597


    Failing input written to testdata\fuzz\FuzzDiv\db4a66cd17474c4b
    To re-run:
    go test -run=FuzzDiv/db4a66cd17474c4b
FAIL
exit status 1
FAIL    example 0.106s

用例执行了一会后就报出了除数不能为 0 的 panic。执行模糊测试的过程中会在当前文件夹生成 testdata 目录,导致用例没有通过的数据会保存在这个目录下,下次再次执行用例的时候会再次使用这些数据作为语料

-fuzztime 控制模糊测试的执行时间:

go test -fuzz . -fuzztime 5s

ref

go-zero 的最佳实践