
测试文件名必须以 _test.go 结尾,且与被测文件同包
Go 的 go test 只会识别 *_test.go 文件,且默认要求测试文件和被测代码在同一个包(package)里。跨包测试不是不行,但属于“黑盒”模式,无法直接访问未导出标识符(比如小写开头的函数、字段),会立刻卡住。
- 正确命名:
calculator.go对应calculator_test.go,都用package calculator - 错误命名:
test_calculator.go或calculator_tests.go——go test直接忽略 - 如果硬要另建
calculator_test包,只能测导出项(ExportedFunc),且需显式导入原包,失去对内部逻辑的覆盖能力
Test 函数必须接收 *testing.T 参数且名称以 Test 开头
Go 测试运行器靠函数签名和命名约定识别测试入口。func TestAdd(t *testing.T) 是唯一被识别的格式;func testAdd(t *testing.T) 或 func TestAdd(t int) 都不会被执行,也不会报错,只会静默跳过。
- 首字母必须大写:
Test,不是test或TEST - 参数类型必须是
*testing.T(功能测试)或*testing.B(性能测试),不能是testing.T(缺少指针) - 推荐命名方式:
Test<code> + 结构体名/函数名 + 场景描述,例如TestCalculator_Add_NegativeNumbers,方便go test -run过滤
表驱动测试中,struct 字段名要对齐可读性,别省略 name 字段
硬编码多个 if 分支写测试容易漏场景、难维护;表驱动是 Go 社区事实标准。但很多人只顾塞 input/output,忽略 name 字段——结果某条 case 失败时,t.Errorf 报错只显示 "got X, want Y",根本不知道是哪组数据挂了。
- 必加
name string字段,值建议体现关键变量,如"two positives"、"nil input" - 避免用下标索引定位:
tests[3]挂了,得数一遍才知道是第几条 - 示例结构体定义:
tests := []struct { name string inputA int inputB int expected int }{{ name: "positive numbers", inputA: 2, inputB: 3, expected: 5, }, { name: "negative and zero", inputA: -1, inputB: 0, expected: -1, }}
go test 默认不运行 Example 函数,但它们影响文档生成和 -test.run 行为
Example 函数(如 func ExampleCalculator_Add())本质是测试,但用途不同:它既验证代码可运行,又作为 go doc 输出的可执行示例。这点常被忽略,导致文档示例过期或本地测试遗漏。
立即学习“go语言免费学习笔记(深入)”;
- 默认
go test不执行Example函数,需加-run=Example显式触发 - 若
Example函数里没调用t.Output或没按格式输出(最后一行必须是注释形式的期望输出),go doc就不展示该示例 - 常见坑:
fmt.Println写死字符串但忘了更新注释行,导致文档和实际输出不一致,用户照着文档抄就出错
setupDB、mustParseJSON)很容易随时间变脏——它们不被 go vet 检查,也不在 CI 覆盖率统计里,但一旦出问题,所有依赖它的测试都会莫名失败。留个心眼,比加一百行注释管用。










