testing.Short()是Go标准方式判断-short标志是否启用,需在测试函数开头配合t.Skip()使用,否则无效;不支持正则负向匹配,应统一用此机制控制耗时测试。

用 testing.Short() 判断是否启用短模式
Go 自带的 -short 标志是跳过耗时测试最轻量、最标准的方式。它不依赖环境变量或自定义逻辑,CI/CD 工具(如 GitHub Actions 的 go test -short)也默认支持。关键在于:你得在测试函数开头主动检查并调用 t.Skip(),否则标志本身不会自动跳过任何东西。
常见错误是只加了 go test -short 却没在代码里响应——结果测试照常跑,超时照样失败。
-
testing.Short()返回true当且仅当命令行传入了-short - 必须配合
t.Skip()使用,例如:t.Skip("slow test skipped in short mode") - 不要在
if !testing.Short() { ... }之外写主逻辑,否则短模式下会执行空分支,可能引发 panic 或未定义行为
在测试函数开头加 t.Skip() 而不是中间或结尾
t.Skip() 是立即终止当前测试函数执行的,类似 t.Fatal(),但标记为 skip 而非 fail。如果把它放在 setup 或 assert 后面,前面的耗时操作(比如启动 mock server、读大文件、sleep)已经执行完了,起不到“跳过”的作用。
典型反例:
func TestHeavyIntegration(t *testing.T) {
db := setupTestDB() // 已经连数据库花了 2s
if testing.Short() {
t.Skip("skipping heavy test")
}
// 此时跳过已无意义
}
正确写法是把检查和跳过放在第一行:
使用 uber-go/dig 在 Golang 中实现依赖注入——基于反射容器,提供 Provide/Invoke、dig.In/dig.Out 参数与结果对象,支持命名依赖等
func TestHeavyIntegration(t *testing.T) {
if testing.Short() {
t.Skip("skipping heavy integration test")
}
db := setupTestDB() // 短模式下这行根本不会执行
}
避免用正则 -run 排除耗时测试
有人想用 go test -run '^(?!TestLegacy|TestSlow).*$' 这类负向匹配来过滤,但 Go 的 regexp 包不支持 (?!...) 语法,实际会静默零匹配——go test 就直接退出,不报错也不提示,看起来像“没测”,容易误判。
更糟的是,正则写错一次,整个测试套件就失效,排查成本高。相比而言,testing.Short() + t.Skip() 是显式、可读、可调试的路径。
- CI 中统一加
-short,本地开发想跑全量就不用它 - 所有耗时测试都走同一套判断逻辑,维护成本低
- 跳过信息会出现在
-v输出里,方便确认哪些被跳过了
注意 t.Skip() 和 t.SkipNow() 没区别,但别用 t.Skipf() 忘记换行
t.Skip()、t.SkipNow() 在当前版本完全等价,都是立刻退出;t.Skipf() 只是带格式化字符串的变体。唯一容易出问题的是:如果你写 t.Skipf("reason %s", "slow") 却忘了末尾换行,某些终端或日志系统可能把跳过消息和后续输出挤在一起,影响排查。
所以建议统一用 t.Skip() 或 t.Skipf("reason %s", "slow") 并确保 message 结尾有句点或换行,让 -v 输出干净可读。
真正复杂的地方不在语法,而在于「哪些测试该标为耗时」——它需要团队对每个 TestXXX 的 IO、网络、计算开销有基本共识。否则,有人写了耗时测试却没加 Short() 检查,CI 就会莫名超时失败。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!










