go单元测试需严格遵循命名、包名、函数签名规范:测试文件须为_test.go、同目录同包;函数必须是func testxxx(t testing.t);运行时需加-v等参数才显示详情。

Go 语言单元测试不需要装框架、不依赖外部工具,go test 命令开箱即用——但前提是文件名、包名、函数签名全对,错一个就静默失败,连报错都不给你。
测试文件命名和位置必须严格匹配
Go 只认 _test.go 结尾的文件,且必须和被测代码在同一个包(同一目录)、同名包声明。比如 utils.go 在 package utils 下,那测试文件就得叫 utils_test.go,开头也得是 package utils。
常见踩坑点:
- 把测试文件放进
test/子目录 ——go test直接无视 - 测试文件用了
package main或其他包名 —— 报错can't load package或静默跳过 - 文件名写成
test_utils.go或utils.test.go—— 不会被识别为测试文件
测试函数签名不能有一丝偏差
必须是 func TestXxx(t *testing.T) 形式:首字母大写的 Test 前缀 + 驼峰名称 + 唯一参数 *testing.T。少个星号、参数名不是 t、多一个参数,都会导致 go test 找不到该函数。
示例正确写法:
func TestAdd(t *testing.T) {
if Add(1, 2) != 3 {
t.Fatalf("expected 3, got %d", Add(1, 2))
}
}
错误写法包括:
-
func testAdd(t *testing.T)(小写 test) -
func TestAdd(t testing.T)(漏掉*) -
func TestAdd(t *testing.T, debug bool)(多余参数)
运行测试时参数要带对才看得见结果
go test 默认只输出 PASS 或 FAIL,不显示函数名、不打印日志、不生成覆盖率——这些都得靠参数手动开。
日常开发建议至少加这两个:
-
go test -v:显示每个TestXxx的执行过程和t.Log/t.Error输出 -
go test -coverprofile=coverage.out && go tool cover -html=coverage.out:生成 HTML 覆盖率报告
其他实用参数:
-
go test -run ^TestAdd$:只跑单个测试,正则锚定避免误匹配 -
go test -count=3:连续跑三次,排查非确定性 bug(如竞态、时间敏感逻辑) -
go test ./...:递归运行所有子目录下的测试(注意是./...,不是.)
并发测试别直接用 time.Sleep 等待
写并发测试时,常见错误是用 time.Sleep 等 goroutine 执行完——这既不可靠(可能睡不够),又拖慢测试速度。应该用同步原语控制流程。
推荐做法:
- 用
sync.WaitGroup等待所有 goroutine 结束 - 用
chan struct{}或sync.Mutex验证状态变更顺序 - 超时控制统一走
context.WithTimeout,避免死等
例如启动 3 个 goroutine 后,别写 time.Sleep(100 * time.Millisecond),而是:
var wg sync.WaitGroup for i := 0; i <p>最易被忽略的是:测试文件改了,<code>go test</code> 不会自动 rebuild;函数逻辑变了,必须手动重跑,它不会监听文件变化。另外,任何未导出的辅助函数(小写开头)可以自由使用,但一旦导出,<code>go test</code> 就可能把它当测试函数解析并报错。</p>
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











