t.Log和t.Logf默认不输出,仅在go test -v时显示,且失败时自动打印;两者均带测试上下文前缀,t.Logf支持格式化,禁用fmt.Println替代。

不加 -v 就看不到 t.Log 和 t.Logf 的输出,这是最常被忽略的前提。
为什么 t.Log 默认不显示
Go 测试框架默认隐藏所有成功测试的调试日志,只在测试失败时自动打印 t.Log 内容(含时间戳、文件名、行号)。这不是 bug,是设计:避免噪音干扰 CI 或本地快速反馈。
- 即使写了
t.Log("got:", result),运行go test也不会输出任何东西 - 只有
go test -v才强制显示全部日志,包括通过的测试 - 子测试(
t.Run)的日志也遵循同一规则,且会自动带上子测试名前缀
必须加 -v,但可以精准控制范围
全量开启 -v 可能刷屏,尤其项目里有几十个测试函数时。用组合参数缩小范围更实用:
-
go test -v -run=^TestParse$:只运行并显示TestParse的日志 -
go test -v -run=TestParse/invalid:只运行并显示名为invalid的子测试日志(需用t.Run("invalid", ...)定义) -
go test -v -failfast:遇到第一个失败就停,但已执行的测试日志仍完整可见
t.Log 和 t.Logf 的行为差异
两者都依赖 -v,但格式化能力不同,选错会影响可读性:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
-
t.Log("key:", k, "val:", v):拼接简单值,类型自动转字符串,但无法对齐或控制精度 -
t.Logf("key=%q, val=%.2f", k, v):支持fmt全部动词,适合结构化输出,比如%+v查看 struct 字段 - 两者输出都带统一前缀:
=== RUN TestXxx\n xxx_test.go:42: key="abc", val=3.14
别用 fmt.Println 替代 t.Log
看似能“看到日志”,但实际埋下多个隐患:
- 无测试上下文:不绑定具体测试函数或子测试,日志混在一起分不清来源
- 并发下乱序:
go test -parallel=4时,fmt.Println输出可能交错,而t.Log由测试框架串行写入 - CI 不识别:
go test -json完全忽略fmt输出,但会把t.Log作为"Action":"output"事件返回 - 子测试中误用外层
t:在t.Run("sub", func(t *testing.T) { fmt.Println(...) })里,日志归属丢失
真正要确认日志是否触发,得靠 -v;真正要验证日志内容是否符合预期,得用 log.SetOutput(&buf) 拦截标准库日志——那是另一类问题,和 t.Log 无关。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










