TestXxx和BenchmarkXxx函数名不可混用:前者仅被go test执行,后者仅被go test -bench=.执行;签名、文件位置、包名、用途均严格区分,混用将导致静默跳过或编译失败。

TestXxx 和 BenchmarkXxx 函数名不能混用
Go 的 testing 包完全靠函数名前缀识别测试类型:只有 TestXxx 才会被 go test 执行,只有 BenchmarkXxx 才会被 go test -bench=. 执行。命名错误不会报错,而是静默跳过——比如把 BenchmarkAdd 写成 TestAdd,再怎么加 -bench 参数也跑不起来。
-
TestXxx函数签名必须是func TestXxx(t *testing.T);BenchmarkXxx必须是func BenchmarkXxx(b *testing.B),参数类型错一个字(比如写成*testing.T)会导致编译失败或无法识别 - 哪怕内容完全是性能逻辑,只要函数名是
TestXxx,go test -bench=.就视而不见;反过来,BenchmarkXxx在go test下也完全不运行 - 常见误操作:在
helper_test.go或internal/子包里定义BenchmarkXxx,但主包没导出、或跨包调用——结果就是BenchmarkAdd-8 0 0 ns/op,迭代次数为 0
执行逻辑完全不同:验证 vs 测量
单元测试是「一次性验证」:每个 TestXxx 只跑一次,靠 t.Errorf 或 t.Fatal 主动标记失败;基准测试是「自动扩缩循环」:每个 BenchmarkXxx 会由框架反复执行,自动调整 b.N 值(比如从 1 到 1000000),直到总耗时稳定在约 1 秒左右,再算出平均值(ns/op)、内存分配(B/op)等指标。
-
go test默认只关心 PASS/FAIL,加-v才显示t.Log输出;而go test -bench=.加-v反而会抑制详细结果,要查分配得加-benchmem,要看单次耗时波动得加-benchtime=100ms - 基准测试中所有初始化逻辑(如构造 map、打开文件)如果写在循环外,只执行一次,但后续
b.N次循环复用同一状态——容易测偏;若写在循环内,又可能把初始化开销计入性能结果 - 想对比两个算法快慢?别手动计时。直接写两个
BenchmarkXxx,再用benchstat工具比对输出,它能告诉你差异是否统计显著
文件和包规则:同包、_test.go、不可导出
所有测试代码必须放在以 _test.go 结尾的文件里,且与被测代码处于**同一包名下**(比如 mymath.go 在 package mymath,那 mymath_test.go 也必须是 package mymath)。跨包调用或挪进 xxx_test 子包,BenchmarkXxx 就不可见。
经过一段时间的开发,以及内部测试,同程网联盟景区新版程序正式发布推出,感谢广大联盟会员一直以来的支持与关注! 同程网联盟景区新版程序新功能介绍:1.统一的页面风格。页面风格将与随后推出的度假线路、酒店、机票以及融合版联盟程序风格保持一直;2.新增后台管理系统。可更加方便快捷的对网站进行个性化设置;3.动态与伪静态切换。后台操作,简单便捷;4.缓存管理。新增缓存,提高网站访问速度,后台可定期清理;5
- 测试文件不会被
go build编译进最终二进制,但会被go test自动加载 - 如果被测函数是小写字母开头(未导出),测试文件必须和它在同一个文件或同包内才能访问;不能靠 import 从外部包调用未导出函数
- 想做全局初始化(比如连接数据库)?可以用
func TestMain(m *testing.M),但注意:它不支持BenchmarkXxx,且必须显式调用m.Run(),否则所有测试(包括基准)都不执行
别把 Benchmark 当 Test 用,也别拿 Test 量性能
有人在 TestXxx 里用 time.Now() 粗略测个耗时,这既不准也不可比——没有自动 warm-up、不控制 GC 干扰、不重复采样、不报告内存。反过来,把 BenchmarkXxx 当功能验证用,比如里面写 if result != 3 { b.Fatal("wrong") },虽然语法合法,但语义错乱:基准测试失败只打印 FAIL,不中断流程,且没人看日志。
立即学习“go语言免费学习笔记(深入)”;
- 功能是否正确?用
TestXxx+ 边界输入 + 错误路径覆盖 - 这段代码到底慢不慢?有没有优化空间?用
BenchmarkXxx+-benchmem+ 多次-count=5跑平均 - 最常被忽略的一点:基准测试默认不重置运行环境。比如你在循环外开了个
sync.Pool,第一次b.N=100后 pool 已有缓存,第二次b.N=10000就占了便宜——这不是真实吞吐,是状态污染










