Go测试函数必须以Test开头且参数为*testing.T;推荐表驱动测试;Mock前需提取小粒度接口;t.Parallel()仅控制调度而非保证并发安全;务必清理测试副作用。

Test函数命名必须以Test开头且参数为*testing.T
Go 的 go test 工具只识别符合特定签名的函数:名字以 Test 开头(首字母大写),且唯一参数类型是 *testing.T。写成 testAdd、Test_add 或 TestAdd(t int) 都不会被发现,运行 go test 时直接显示 “no tests to run”。
- 正确写法:
func TestReverseList(t *testing.T) - 常见错误:函数名含下划线(
Test_reverse_list)、小写开头、参数类型错(如*testing.B或无参) - 注意包作用域:测试函数和被测代码需在同一个包内(或通过导出接口访问),否则无法调用内部函数
表驱动测试比多个独立Test函数更易维护
当你需要验证同一函数在不同输入下的行为(比如空切片、单元素、负数、边界值),硬写十几个 TestXxxCase1、TestXxxCase2 会迅速失控——命名重复、逻辑分散、新增用例要复制粘贴。
- 推荐结构:用
[]struct{input, want interface{}}切片组织用例,循环执行断言 - 优势:新增 case 只需往切片里加一行;失败时
t.Errorf("case %q: got %v, want %v", tc.name, got, want)能精准定位哪条数据出错 - 陷阱:别在循环里漏掉
t.Run——否则所有子测试共用一个t实例,t.Fatal会提前终止整个循环,掩盖后续用例问题
Mock外部依赖前先提取接口,而非直接 mock struct
想测一个依赖数据库的 service 层?别试图 mock 具体的 *gorm.DB 或 *sql.DB 实例——它们没接口,gomock 生成不了合法 Mock 类型,强行反射或 monkey patch 会导致测试脆弱、难调试。
- 正确路径:定义精简接口,例如
type UserRepository interface { FindByID(id int) (*User, error) } - 让真实实现和测试 Mock 都实现该接口,业务代码只依赖接口
- 关键点:接口粒度要小(单一职责),避免
Repository这种大而全的接口,否则 Mock 行为难设定、测试易耦合
t.Parallel() 不等于并发安全,它只控制测试执行调度
加了 t.Parallel() 后测试跑得更快,但如果你的被测函数或 setup 代码本身不是并发安全的(比如共享全局 map、未加锁的计数器),结果仍是不可靠的——失败可能偶发、难以复现。
立即学习“go语言免费学习笔记(深入)”;
-
t.Parallel()仅告诉go test:“这个测试可以和其他 Parallel 测试一起跑”,不提供任何同步保障 - 真正需要并发测试时:用
sync.WaitGroup+ 多 goroutine 调用被测函数,再用t.Log或 channel 收集结果做断言 - 容易忽略:测试文件里多个
TestXxx函数默认串行,即使各自调用了t.Parallel(),也只在本函数内启用并行调度


















