test函数必须以大写字母开头,因为go test仅识别func testxxx(t *testing.t)形式的导出函数,xxx首字母需大写且后缀为合法标识符(非数字或下划线结尾);文件名须为xxx_test.go且与源码同目录,包声明须一致;t.run子测试名须唯一以防覆盖;临时禁用测试应改名而非t.skip()以避免副作用执行。

Test函数为什么必须以大写字母开头?
Go 的 go test 命令只认签名合法的函数:必须是 func TestXxx(t *testing.T),其中 Xxx 首字符必须为大写字母。这不是风格建议,而是硬性过滤规则——Test123、Test_parse、Test_ 全部被静默忽略,连报错都不会有。
-
TestAdd✅ 合法,首字母大写 + 驼峰后缀 -
testAdd❌ 小写开头 → 不运行 -
TestAdd_❌ 下划线结尾 → 不运行 -
TestAdd01❌ 后缀纯数字 → 不运行(Go 认为它不是“标识符”)
背后原因是 Go 测试发现机制依赖 reflect 检查函数名是否符合导出标识符规则(即首字母大写),而数字/下划线开头的后缀不满足该条件。
测试文件名和包声明怎么配才不被 go test 忽略?
文件名没写对,整个测试就等于不存在;包声明错了,可能连私有函数都测不了。
- 文件名必须是
xxx_test.go,且与被测源码在**同一目录下**(比如user.go对应user_test.go) - 包声明必须与源码一致:
package user(不是package user_test,除非你明确想做黑盒测试) - 不能放在
test/或tests/子目录里——go test不会递归扫描子目录找测试
常见现象:改完测试代码,执行 go test 却显示 ok . 0.001s,零测试用例跑过。八成是文件名没带 _test.go,或者包名写成了 package main_test 却想测 package calculator 的内部逻辑。
立即学习“go语言免费学习笔记(深入)”;
表驱动测试中 t.Run 的 name 字段为什么不能重复?
子测试名重复不会报错,但会导致后一个覆盖前一个——你看到的失败信息、覆盖率统计、甚至 go test -run 过滤结果,全都不准。
- 错误写法:
t.Run("valid", ...)在循环里多次调用,每次 name 都是"valid" - 正确做法:用输入特征构造唯一名,比如
fmt.Sprintf("input_%s", tt.input)或直接用 map key(如"valid_http_url") - 别省事写
t.Run("case1", ...)—— 一失败你根本不知道是哪个 case
更隐蔽的坑:循环变量复用。写成 for _, tc := range tests { t.Run(tc.name, func(t *testing.T) { ... }) } 看似没问题,但如果 tc 是外部声明的变量(而非 for _, tc := range 中定义),所有子测试闭包会共享最后一次迭代的值。
临时禁用某个测试,为什么推荐改名而不是用 t.Skip()?
t.Skip() 表面跳过,实则仍会进入函数体执行——初始化资源、发 HTTP 请求、连接数据库……这些副作用照常发生,只是最后不报错而已。
- 改名更干净:
TestValidateEmail→TestValidateEmailDisabled,go test直接无视 -
t.Skip()适合“运行时条件判断跳过”,比如只在 CI 环境跳过集成测试;不适合开发阶段随手禁用 - 尤其注意:如果测试里有
defer cleanup(),t.Skip()不影响 defer 执行,但你可能根本没意识到 cleanup 被触发了
真正容易被忽略的是并发安全——多个子测试共用一个全局变量或未加锁的 map,名字一改就暴露问题;而 t.Skip() 让问题继续潜伏。










