如何在Go Fuzzing中查看所有模糊测试用例的输入参数(含非失败用例)
我完全懂你的需求——想看到模糊测试生成的每一个输入,不管测试成功还是失败,尤其是像你说的,当函数有边界约束没实现时,能通过fuzz的输入及时发现这些遗漏的场景。
首先得说清楚为什么你用t.Log、t.Error这些方法看不到所有输入:Go的fuzz测试默认会静默执行大量生成的用例,只有当测试用例失败时,才会打印该用例对应的t.Log日志。对于成功的用例,测试框架不会输出任何日志,所以你看不到那些符合预期的输入。
那该怎么解决呢?分两种场景给你具体方案:
场景1:关注边界/异常用例(推荐)
像你提到的场景——函数需要限制输入在123 < field < 321之间,那我们可以主动在fuzz测试里加入这个检查,一旦输入超出范围就触发错误,这样不仅能看到这些问题用例的输入,还能让fuzz测试把这些边界用例保存下来,后续会优先测试这类场景。
修改你的代码如下:
func FuzzF(f *testing.F) { f.Fuzz(func(t *testing.T, a float64){ // 主动检查你需要的边界约束 if a <= 123 || a >= 321 { t.Errorf("输入值超出预期范围: %.2f", a) } // 这里放你原本的测试逻辑,比如调用待测试的解析函数 // parseResult, err := YourParseFunc(a) // ... }) }
运行测试时,只要fuzz生成了超出(123,321)范围的输入,就会触发t.Errorf,此时测试框架会打印这个输入值,同时把这个用例加入到fuzz的种子库中,后续会生成更多类似的边界用例帮你验证。
场景2:确实需要查看所有输入(不推荐,输出量极大)
如果你一定要看到每一个fuzz生成的输入,不管成功失败,可以直接用fmt.Println代替t.Log——因为fmt的输出是直接写到标准输出,不受测试框架的日志控制:
func FuzzF(f *testing.F) { f.Fuzz(func(t *testing.T, a float64){ fmt.Printf("当前fuzz输入A: %.2f\n", a) // 你的测试逻辑 }) }
然后运行测试命令:
go test -fuzz=FuzzF
这样就能看到每一个生成的输入了,但要注意:fuzz测试会生成上百万甚至更多的用例,输出量会非常大,建议把输出重定向到文件查看,比如:
go test -fuzz=FuzzF > fuzz_inputs.log
最后补充一句:其实大部分场景下,优先用第一种方法更高效——聚焦你关心的边界场景,既不会被海量输出淹没,又能精准发现未实现的约束。
备注:内容来源于stack exchange,提问作者Nikola Cekić

