go test -cover 显示 0.0% 表示未运行任何测试,常见原因包括_test.go 文件名错误、测试函数未以test开头、在错误目录执行命令、或未编写test函数;需先用go test -v确认是否执行测试,再通过go tool cover -func分析具体未覆盖函数。

go test -cover 显示 0.0% 是没跑测试,不是覆盖率低
你执行 go test -cover 看到 coverage: 0.0% of statements,大概率根本没触发任何测试。这不是代码难测,是测试没被识别。
常见原因包括:
-
_test.go文件名写错,比如叫handler_tests.go或test_handler.go(必须是_test.go结尾) - 测试函数没以
Test开头,例如写了func checkLogin()(必须是func TestLogin(t *testing.T)) - 在错误目录运行命令:被测代码在
internal/service/,却在项目根目录只跑go test -cover(它默认不递归子包) - 没写任何
func TestXxx(t *testing.T),只写了辅助函数或main
先运行 go test -v,确认输出里有 === RUN TestXXX 才算真正开始跑测试。
用 go tool cover -func 定位真正该补的函数
go test -cover 输出的总百分比毫无定位价值。必须生成 profile 并查函数级明细:
go test -covermode=count -coverprofile=coverage.out . go tool cover -func=coverage.out
重点关注 coverage 列为 0.0%、33.3% 或 50.0% 的函数——这些数字背后通常是:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
-
if err != nil { return }分支完全没进过,因为 mock 总返回nil -
else块写在if len(s) == 0后,但测试只传了非空切片 -
defer里的日志或close调用,因函数提前return没执行 - 带
context.Context的函数,测试没传已cancel的ctx,导致超时路径沉默
error 分支必须显式构造,不能靠“自然失败”
Go 的错误处理是显式的,但多数测试只走 happy path。真实服务里,db.QueryRow 失败、http.Do 超时、json.Unmarshal 解析空 body —— 这些都得手动造出来。
实操建议:
- 对每个返回
error的外部调用,mock 至少定义两条行为:mock.On("GetUser").Return(user, nil)和mock.On("GetUser").Return(nil, errors.New("timeout")) - HTTP handler 测试中,用
httptest.NewRequest("POST", "/api", nil)触发 body 读取失败;用bytes.NewReader([]byte(""))模拟空 JSON - 注意
nil切片和空切片的区别:var s []string = nil与s := []string{}在len(s) == 0后可能触发不同分支,都要覆盖
表格驱动 + context 控制,精准命中取消/超时分支
别在测试里写 time.Sleep(1 * time.Second) 等超时,既慢又不可靠。把 context 构造也纳入表格驱动:
tests := []struct {
name string
ctx func() context.Context
wantErr bool
}{
{"normal", func() context.Context { return context.Background() }, false},
{"ctx cancelled", func() context.Context { ctx, cancel := context.WithCancel(context.Background()); cancel(); return ctx }(), true},
{"ctx timeout", func() context.Context { return context.WithTimeout(context.Background(), 1*time.Millisecond) }(), true},
}
这样能稳定触发 ctx.Err() != nil 分支,且无需等待。
真正卡住覆盖率提升的,从来不是语法或框架,而是那些没被触发的 if err != nil、else、defer 和 context 取消路径——它们一旦在线上沉默执行,就容易变成 panic 或资源泄漏。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










