Go测试函数必须严格遵循func TestXxx(t *testing.T)签名及命名规范,否则go test会静默跳过——不执行、不报错;文件须以_test.go结尾且与被测代码同包同目录。

go test 能跑起来,不代表你的测试真的被运行了——最常见的情况是函数名、文件名或包位置不对,导致 go test 静默跳过,连失败提示都没有。
Test函数名和签名必须严格符合约定
Go 不做任何宽容处理:函数名必须以大写 Test 开头,后面接首字母大写的标识符;参数只能是 *testing.T,不能多也不能少。
-
TestAdd✅,testAdd❌(小写 t),Test_add❌(下划线),TestAdd(t *testing.T, extra string)❌(多参数) - 函数不能有返回值,哪怕只是
func TestAdd() (bool)也会被忽略 - 如果报错类似
missing argument或cannot use ... as type testing.T,八成是签名写错了
_test.go 文件必须和被测代码同包同目录
测试文件不是随便放哪都行。它必须和你要测的 .go 文件在同一个目录、声明同一个包名(比如都是 package main 或 package utils),否则无法访问非导出函数,go test 也可能找不到目标。
- 错误做法:把
utils_test.go放在test/子目录下,或改成package utils_test - 正确做法:
utils.go和utils_test.go并列放在同一目录,且都写package utils - 如果你测的是私有函数(如
parseConfig),这点尤其关键——跨包无法调用,也没法测
t.Error 和 t.Fatal 的行为差异直接影响调试效率
它们看起来都报错,但执行流控制完全不同,选错会导致漏掉关键失败点。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
-
t.Error/t.Errorf:记日志后继续执行,适合校验多个条件(比如检查返回值 + error 是否为 nil) -
t.Fatal/t.Fatalf:记日志后立刻退出当前测试函数,适合前置检查失败(如 mock 初始化失败、临时目录不可写) - 典型坑:在表驱动循环里用
t.Fatal判断输入合法性,结果只测了第一个 case 就终止,后面全跳过
用 t.Run 做子测试才能真正定位到具体场景
单个 TestXxx 函数里硬写 if 判断,失败时你只知道 “TestXxx 失败”,但不知道是哪组输入出问题。用 t.Run 是 Go 官方推荐的组织方式。
立即学习“go语言免费学习笔记(深入)”;
- 每个子测试独立运行,失败互不影响
-
go test -v会显示完整层级,如TestAdd/positive_input - 支持单独运行:
go test -run="TestAdd/negative" - 注意闭包陷阱:别在 for 循环里直接捕获
tt变量,要用tt := tt显式复制
t.Cleanup 关闭临时文件或 mock server)。别指望框架替你发现路径或包名错误,Go 的约定就是这么直白又不容商量。

















