go test 是唯一必须掌握的入口,但需按场景拆解使用:测试文件须与被测代码同目录同包,命名 *_test.go 且含 testxxx 函数;集成测试需构建标签和守卫;依赖须接口注入或参数化;-race 不适用于集成测试。

go test 是唯一必须掌握的入口,但微服务里光跑 go test 会立刻踩坑——它默认只扫当前包、不连外部依赖、不区分测试类型。真正能落地的测试方法,得按场景拆开用。
TestXxx 函数和 *_test.go 文件怎么放才有效
Go 不靠目录结构或框架识别测试,只认两件事:_test.go 文件名 + TestXxx 函数签名(首字母大写、参数为 *testing.T)。这两样缺一不可。
- 测试文件必须和被测代码在**同一目录、同 package 声明**,否则访问不到未导出字段或函数,比如
internal/service/user.go的测试只能放在同一目录下,命名为user_test.go,且声明package service - 常见错误:把
user_test.go放到cmd/或test/目录下 → 包名变成main或test,编译报undefined: CreateUser - 哪怕只测一个私有 helper 函数,也得遵守这个规则——没有例外
集成测试必须显式启用,否则根本不会跑
go test 默认只运行单元测试。集成测试要连 DB、HTTP、Redis,不能让它随随便便就执行,否则本地开发或 CI 都会卡死或 panic。
Go 配置库,使用 spf13/viper — 分层优先级(flag > env >file > KV > default),提供 BindPFlag/BindPFlags、SetEnvPrefix + SetEnvKeyReplace 等功能。
- 用构建标签控制:在集成测试文件顶部加
//go:build integration,再通过go test -tags=integration ./...显式启用 - 文件命名建议用
_integration_test.go后缀(如order_integration_test.go),不是强制,但一眼能区分 - 每个集成测试开头加守卫:
if testing.Short() { t.Skip("skipping integration test") },配合go test -short快速跳过 - 再加一层依赖探活,比如
db.Ping()失败就t.Skipf("DB unreachable"),避免超时挂住
mock 和 real 依赖切换失败,90% 是因为没切断初始化链
测试里 mock 失效,不是 mock 写得不对,而是真实 client 被提前 new 出来了。
- 绝对不要在
init()、包级变量、全局单例里初始化 DB/HTTP client —— 它们会让测试互相污染,t.Cleanup都救不回来 - 可靠切换方式只有两种:
– 接口注入:把*sql.DB换成DBExecutor接口,测试传 mock 实现,生产传真实实例
– 构造函数参数化:service 初始化时所有依赖(DB、HTTP client、cache)都作为参数传入,测试塞 mock,main函数里才 new 真的 - 如果用了第三方 SDK(比如 AWS SDK),优先用其官方提供的 interface(如
aws.Client)而非具体 struct,方便替换
go test -race 和集成测试别混着跑
集成测试常启 goroutine、复用连接池、共享 transport,-race 一开必报 data race —— 这不是 bug,是预期行为。
- 单元测试可以放心加
-race,轻量、隔离、无副作用 - 集成测试默认禁用
-race;CI 脚本里明确写成go test -short ./... -race(不含集成) - 真要排查 race?单独跑某个集成测试,去掉
-race,用go run -race跑对应 main 或用go test -run TestName配合-race局部验证
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










