golangci-lint 默认跳过 _test.go 文件,需同时清空 skip-files 并启用 --tests 参数,再针对性配置 staticcheck、gosimple、unused 三个低误报 linter 才能有效检查测试代码。

golangci-lint 默认不检查 _test.go 文件
它默认跳过所有以 _test.go 结尾的文件,哪怕你写了 golangci-lint run ./...,测试文件里的 errcheck 漏判、staticcheck 误用弃用 API、未使用的变量等都不会被发现。这不是 bug,是设计行为——因为很多 linter(比如 govet)在测试上下文中会报大量误报(如 time.Sleep 被标为“阻塞”,log.Fatal 在测试里合理但被 errcheck 报错)。
显式启用测试文件检查需两步:改 skip-files 和调低误报敏感度
必须同时做以下两件事,缺一不可:
- 在
.golangci.yml的run区块中移除对_test.go的默认跳过:skip-files: [](清空)或明确排除其他不需要的路径,但不写.*_test\.go - 为易误报的 linter 单独配置宽松规则,例如:
—errcheck需禁用对log.Fatal、t.Fatal等测试函数的检查,通过errcheck: check-exported: false或自定义exclude-functions
—govet的shadow检查在测试中常因for _, tt := range tests误报,可关掉:govet: enable-all: true; disable: ["shadow"]
测试专用规则推荐只开这 3 个 linter
全量开启所有 linter 到测试文件里,只会让 CI 变慢、告警变水。实际项目中真正值得开的只有:
-
staticcheck:能抓到json.Unmarshal类型错配、time.After在 for 循环里滥用等线上高频故障点,且在测试中误报率极低 -
gosimple:识别测试中冗余断言(如if !ok { t.Fatal() }可简化为require.True(t, ok)),前提是和staticcheck不同时启用(二者重叠高,重复报) -
unused:检查测试文件里未使用的var tt testCase、废弃的benchTest函数,清理技术债务很有效
别碰 revive 或 gofmt 的测试专用规则——前者规则粒度太细、难收敛,后者格式化测试代码没实质收益。
CI 中跑测试检查必须加 --config 参数
本地 golangci-lint run 可能自动读到 .golangci.yml,但 CI 环境(尤其是 GitHub Actions 或 Jenkins)经常因工作目录或缓存问题漏读配置。务必显式指定:
golangci-lint run --config=.golangci.yml --tests ./...
注意:--tests 是关键开关,它告诉 golangci-lint 主动包含 _test.go;没有它,即使配置里清空了 skip-files,也不会生效。另外,多 module 项目中,每个 module 的 .golangci.yml 都得单独加这一行,不能靠根目录配置继承。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











