直接回答:表驱动是 Go 测试的通行结构:定义匿名结构体切片(name、输入、期望输出、可选 setup),for _, tt := range testst.Run(tt.name, ...) 子测试。好处一目了然:加用例只是加一行数据、失败时子测试名直接定位、可用 t.Parallel() 并行。fuzz 测试不同:你提供种子语料和"不变量"断言,go test -fuzz 自动生成变异输入轰炸函数,专找解析器、编解码、边界处理里人类想不到的崩溃和逻辑漏洞。

展开解析:表驱动的细节经验:用 tt := tt(1.22 前)避免闭包捕获陷阱;期望与实际差异用 t.Errorf("got %v, want %v") 报出;复杂比较上 go-cmp。fuzz 的姿势:f.Add(种子) 提供合法与近合法的起点;函数体内不判 error 而是断言不变量(如 Decode(Encode(x)) == x、绝不 panic);跑出的崩溃自动落盘 testdata 成为回归用例——这是 fuzz 的隐藏收益。fuzz 与单测的分工:单测验证已知正确性,fuzz 探索未知错误,解析外部输入的代码(协议、文件格式)都该配 fuzz。CI 里 fuzz 跑固定时长(-fuzztime=30s)而非无限跑,种子语料入库共享。

追问方向:1.22 的 range 变量语义变化解决了什么?fuzz 语料库如何维护?property-based 测试与 fuzz 的关系?

(约 440 字)