Go测试需显式比对got/want变量并输出两者,禁用内联判断;多返回值须解构验证error和结果;表驱动测试用语义化结构体字段;指针/接口只校验nil性;所有返回值必须显式消费。

Go 原生测试不提供断言函数,验证返回值必须靠显式比较 + t.Errorf,否则你看到的失败日志只有模糊提示,根本没法定位问题。
用 got/want 变量显式比对返回值
别写 if Add(2, 3) != 5 这种内联判断——它让错误信息无法同时展示实际值和期望值,调试时得重跑一遍才能知道 Add(2, 3) 究竟返回了啥。
- 必须拆成
got := Add(2, 3)和want := 5两步,这是 Go 社区硬性约定 -
t.Errorf("Add(2,3) = %d, want %d", got, want)要同时输出两者,失败时一眼看出偏差 - 别用
t.Fatal或t.Fatalf替代t.Errorf,否则单个 case 失败就中断整个测试循环,漏掉其他潜在问题
多返回值函数必须逐项验证 error 和结果
像 func divide(a, b int) (int, error) 这类函数,只检查 result 不检查 err 是常见漏洞。nil 的 error 不代表成功逻辑正确,非 nil 的 error 也不代表 result 无效(有些函数会返回部分有效值)。
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
- 测试里必须解构:
got, err := divide(4, 2) - 先用
if err != nil分支处理错误路径,再用errors.Is(err, xxx)或errors.As(err, &e)检查具体错误类型 - 成功路径下仍要验证
got是否等于预期,不能默认“没 err 就一定对”
表驱动测试中为多返回值设计结构体字段
别把多个返回值塞进一个 out string 字段然后用字符串比较——类型不安全、不可调试、重构时极易断裂。
- 结构体字段要与返回值一一对应,命名带语义,比如
outInt、outEven、outErr - 测试循环内直接解构:
gotInt, gotEven := half(tt.in),再分别比对gotInt != tt.outInt和gotEven != tt.outEven - 错误字段统一用
error类型(不是string),方便后续用errors.Is做精准匹配
测试指针或接口返回值时只校验 nil 性
当函数返回 *CustomType 或 io.Reader 时,别写 if got == tt.want —— 这既比较地址又可能 panic(解引用 nil 指针),而且语义错误(你真正关心的是“有没有值”,不是“是不是同一个对象”)。
- 用
(got == nil) != (tt.want == nil)判断存在性是否一致 - 如果需要进一步验证非 nil 值的内容,应在 nil 检查通过后再调用
assert.Equal或手动深比较,避免提前 panic - 注意:反射获取返回值类型时,
error的.Name()是空字符串,得用.String()才能拿到 "error"
最易被忽略的一点:所有返回值,无论是否带 error,都必须在测试中显式消费。漏掉任何一个,就等于放过了一个可能静默失败的分支。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










