真正要盯的是未执行的错误处理分支,如if err != nil等,需用go tool cover -func定位0.0%覆盖函数,通过mock、context取消、表格驱动和依赖注入确保所有分支被验证。

覆盖率数字高不等于业务逻辑被真正验证过,真正要盯的是那些没执行的 if err != nil、len(s) == 0、ctx.Err() != nil 分支——它们一旦跳过,线上就可能 panic 或数据错乱。
用 go tool cover -func 快速定位低覆盖业务函数
别只看 go test -cover 输出的总体百分比。那个数字会掩盖关键失衡:比如工具函数 100%,而核心 ProcessOrder 函数里数据库写失败后直接 log.Fatal 的三行永远红色。
- 先运行
go test -coverprofile=coverage.out ./...生成数据 - 立刻执行
go tool cover -func=coverage.out,重点关注 coverage 值为0.0%或33.3%的函数——这些往往对应未触发的else、return err或defer清理逻辑 - 避免初期用
-covermode=count;默认set模式更快暴露“是否执行”,比“执行几次”更贴近测试意图
补 error 分支必须显式 mock,不能靠环境“碰运气”
业务函数里大量防御逻辑藏在 if err != nil 后面,但多数测试只传合法参数、连真实 DB 都跑通就收工,导致这些分支根本没进过。
- 对每个返回
error的依赖调用,mock 至少设两条路径:mock.On("CreateUser").Return(user, nil)和mock.On("CreateUser").Return(nil, errors.New("duplicate email")) - HTTP handler 测试中,用
httptest.NewRequest("POST", "/order", bytes.NewReader([]byte("")))强制触发 JSON 解析失败 -
context相关分支别用time.Sleep等超时:构造已 cancel 的 ctx(ctx, cancel := context.WithCancel(context.Background()); cancel(); return ctx)或超短 timeout(context.WithTimeout(context.Background(), 1*time.Millisecond))
用表格驱动 + 子测试覆盖组合边界场景
一个带两个 if 的订单校验函数,至少有 4 种路径。手写 4 个独立 TestXxx 函数重复且难维护,还容易漏掉交叉情况。
初始化并管理阿里云SDK Go 客户端,涵盖 sync.Once 单例、goroutine 安全、endpoint 与 region 配置、VPC 端点及调试。
立即学习“go语言免费学习笔记(深入)”;
- 把输入、期望 error、是否应 panic 打包成 struct 切片,用
for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { ... }) }驱动 - 特别注意边界:空字符串、
nil切片(不是空切片)、负数 ID、超长字段——这些常触发不同分支,例如ValidateEmail("")和ValidateEmail("abc.com")就分别击中len(s) == 0和strings.Contains(s, "@") == false - 子测试名带上关键变量,如
"with_empty_items"或"ctx_cancelled",生成的 HTML 报告里能直接定位哪条路径没跑
拆函数 + 依赖注入,让不可控逻辑可测
直接在业务函数里调 time.Now()、rand.Intn() 或全局 db 实例,等于把测试绑死在环境上——你永远没法稳定触发 if err != nil。
- 把时间/随机逻辑抽成函数变量:
var nowFunc = time.Now,测试时替换为固定时间 - 提取接口:
type PaymentClient interface { Charge(ctx context.Context, amount int) error },业务函数接收该接口而非具体实现 - 测试中传入 mock 实例,让它按需返回
nil、error或特定数据;每次 mock 调用后加mock.AssertExpectations(t),防止忘了设期望却误以为测试通过
真正卡住覆盖率提升的,从来不是工具不会用,而是没意识到:未覆盖的那几行,常常是唯一能防止线上雪崩的防线。它们不红在报告里,就红在生产日志里。

















