Go 自带的 go test ./... 足够好用,但项目包一多,输出就会变得有点难看。
尤其是在 CI 里,几十个包一起跑,真正失败的测试夹在一堆 ok 和日志中间,不太容易第一眼看到问题。
这时候 gotestsum 会舒服很多。
我第一次明显感觉到它有用,是 CI 里有个测试偶发失败,日志里前后混着很多包的输出。go test 不是不能看,但每次翻日志都要先定位失败包、失败用例、失败前后的输出。gotestsum 做的不是增强测试能力,而是把定位成本降下来。
它解决的是输出体验
gotestsum 本质上还是跑 go test,不是替代 Go 的测试框架。它主要做两件事:
- 整理测试输出,让成功、失败、跳过更清楚。
- 生成 CI 更容易消费的报告,比如 JUnit XML。
本地可以直接这样跑:
| |
注意 -- 后面的参数会传给 go test,所以原来的测试参数基本还能继续用。
比如只跑某个测试:
| |
加 race:
| |
在 CI 里生成 JUnit 报告
很多 CI 系统都能识别 JUnit XML。gotestsum 可以直接生成:
| |
这样失败测试会在 CI 的测试报告里展示,不用每次去日志里慢慢翻。
如果项目有多个模块,也可以按模块分别输出报告,避免一个巨大文件不好定位。
我还会把普通测试和 CI 测试分开。普通测试追求快,CI 测试可以更严格:
-count=1 可以避免测试缓存干扰 CI 判断。不是每个项目都必须加,但排查偶发问题时很有用。
如果项目用 Makefile:
如果项目用 Taskfile:
本地默认命令不要太重,CI 命令可以加 -race、coverage 或报告输出。
不要让测试日志污染输出
gotestsum 能改善展示,但救不了测试里乱打日志的问题。
如果测试里大量 fmt.Println,CI 输出一样会很吵。我的习惯是:
- 正常测试不要随便打印。
- 调试信息用
t.Logf。 - 只有测试失败时再看详细上下文。
- 集成测试和单元测试尽量分开。
工具只是把结果排得更清楚,测试本身还是要保持干净。
gotestsum 不是必须品,但它很适合中大型 Go 项目。它没有改变测试写法,也没有引入新的断言风格,只是让 go test 的结果更好读。
如果一个项目已经开始觉得 CI 测试日志难看,我会优先接入 gotestsum,而不是换测试框架。