go test 默认不递归子目录,必须显式使用 ./ 才能覆盖 internal/、cmd/ 等子包;t.parallel() 不提供并发安全,禁止共享状态;表驱动测试子名称须唯一,否则 -run 过滤失效。

go test ./ 是默认不递归的,必须显式写
很多人以为 go test 会自动扫完整个项目,结果 CI 里漏测了 internal/ 或 cmd/ 下的包,覆盖率虚高。根本原因是:默认只跑当前目录,./ 才表示“当前及所有子目录”。
-
go test→ 只跑当前目录下的*_test.go -
go test ./→ 扫描所有子模块,包括./internal/utils、./cmd/server等 -
go test .→ 和go test行为一致,不递归,容易误用 - 想排除某些目录(比如
examples/),别用-exclude(Go 1.21+ 才支持),改用:go test $(go list ./ | grep -v examples)
t.Parallel() 不等于并发安全,共享变量必出竞态
看到 t.Parallel() 就在循环里改全局计数器?这是最典型的误用。它只告诉测试框架“这个子测试可以和其他并行跑”,但不提供任何锁或同步机制。
Go语言(Golang)1.26.0版本提供 Go 官方 Windows amd64 MSI 安装包下载入口,版本号 1.26.0,可用于旧项目维护、兼容性测试和指定版本开发环境配置。
- 并行测试中禁止读写包级变量、全局 map、未加锁的 slice
- 需要验证并发行为时,应单独写一个
TestConcurrentUpdate,内部用sync.WaitGroup控制 goroutine,并用t.Log记录中间状态 -
t.Parallel()必须放在t.Run()的函数体内,写在循环外无效 - 如果子测试依赖外部状态(如临时文件、环境变量),并行执行会互相干扰,应显式
t.Skip()或拆成串行测试
表驱动测试里 name 字段重复会导致 -run 过滤失效
go test -run TestParse/valid 只匹配第一个子测试,其余同名的被跳过——不是 bug,是 Go 测试引擎的设计:子测试名必须唯一,否则无法精确定位。
- 别用硬编码字符串如
"valid"或"case1"作为t.Run()的第一个参数 - 推荐生成唯一 name:
fmt.Sprintf("parse_%s_%x", tc.desc, sha256.Sum256([]byte(tc.input)).[:4]) - name 中含
/会自动形成层级,比如"Parse/empty_input"和"Parse/nil_slice"可被-run Parse/一起匹配 - 空字符串或全空格的 name 会让
-run无法按前缀过滤,且 IDE 跳转失效
测试文件名和包名错一位,整个测试就静默消失
测试文件没跑、没报错、也没输出,最常见的原因是:文件没放对位置,或包声明不对。Go 不报错,只是默默跳过。
- 测试文件必须和被测代码在同一包、同一目录,且以
_test.go结尾;放在test/目录或单独建test包,go test完全无视 - 测试文件里的
package声明必须和源文件一致(比如都是package utils),不能写成package utils_test(那是用于定义内部测试辅助类型的特殊包) - 测试函数必须是
func TestXXX(t *testing.T),首字母大写的Test缺一不可;testXXX或Test_xxx都不会被识别 - 如果用了
go mod,确保go test在 module 根目录或子包内执行,否则可能因 import path 解析失败而静默退出
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










