go test仅识别以_test.go结尾的文件及其中形如func TestXxx(t *testing.T)的函数(Xxx首字母大写),测试文件须与被测代码同目录同包,否则静默忽略。

go test 能识别的测试文件和函数长什么样
GoLand 本身不决定哪些是测试,真正起作用的是 go test 的扫描规则。它只认两类东西:*_test.go 文件,以及文件里形如 func TestXxx(t *testing.T) 的函数(Xxx 必须首字母大写,不能是 Test_add、testAdd 或 Test123)。其他命名全被忽略,哪怕你写了 func CheckAdd(t *testing.T),go test 也不会执行它。
常见错误现象包括:测试函数运行不了、go test -v 输出里完全没看到你的测试名、CI 上测试通过但本地没跑——大概率就是命名没对上。
-
calculator.go对应的测试文件必须叫calculator_test.go,不能叫test_calculator.go或calculator_tests.go - 函数名必须是
TestAdd,不是testAdd、Testadd、Test_Add、AddTest - 测试文件必须和被测代码在同一个目录、同个包(即
package calculator),不能写成package calculator_test—— 后者会导致无法访问未导出函数
在 GoLand 里快速生成合规测试骨架
GoLand 提供了快捷键支持,但默认行为不一定符合规范,得手动调一下设置。右键函数 → Go to → Test for … 或按 Ctrl+Shift+T(macOS 是 ⌘⇧T)能弹出创建选项,但要注意:
- 勾选 “Create test file in same directory” —— 否则可能建到错目录,
go test找不到 - 确保 “Test package name” 显示的是原包名(比如
calculator),不是带_test后缀的变体 - 生成的函数模板里,参数必须是
t *testing.T,不能漏掉*或写成testing.T - 如果 GoLand 自动生成了
func TestXxx(t *testing.B)(性能测试模板),要立刻改成*testing.T,否则不会被当单元测试执行
t.Run 是子测试的唯一可靠组织方式
别在一个 TestXxx 函数里堆多个 if 判断加 t.Errorf。那样失败时只能看到 “TestXxx failed”,根本不知道是哪组输入挂了。用 t.Run 才能精准定位、单独重跑、并行执行。
典型错误写法:if got != want { t.Errorf("…") } 连续写三遍,第一个失败后第二个仍会执行,可能因状态污染导致 panic;正确写法是每个 case 封进 t.Run 闭包里。
GoLand 2026.1.1 是 2026.1 发布后的首个维护修正版本,适合已经开始体验 2026.1 新功能并希望同步补丁的开发者。它更适合用于入门项目、现有项目迁移测试和 IDE 行为验证。
- 子测试名别用空格或特殊字符,比如
t.Run("1+2=3", …)在go test -run过滤时容易出问题,推荐用"one_plus_two" - 循环中必须显式重声明
tt := tt,否则所有闭包共享最后一个tt值 —— 这是 Go 常见陷阱,不加这句所有子测试都会跑最后一条用例 - 想跳过某个子测试?直接在
t.Run里调t.Skip(),比整个函数改名更安全,且不会触发初始化副作用
覆盖率和并发安全是上线前最容易被跳过的检查项
GoLand 的 “Run with Coverage” 按钮点一下就能看数字,但数字本身没意义。关键是要确认:边界值有没有覆盖?错误路径有没有走通?比如除零、空输入、超长字符串 —— 这些往往不在主流程里,但 go test -coverprofile=c.out && go tool cover -html=c.out 能直观暴露盲区。
另一个隐形炸弹是并发安全。GoLand 默认允许所有 TestXxx 并发执行,如果你的测试里用了全局 map、缓存变量或临时文件路径没隔离,就可能出现偶发失败。每次提交前跑一次 go test -race 是底线操作,不是可选项。
最常被忽略的是清理逻辑:文件没删、端口没关、goroutine 没等完。用 t.Cleanup(func(){…}) 注册释放动作,它会在测试函数返回前(包括被 t.Fatal 中断时)一定执行,比 defer 更可靠。










