Go测试文件必须与源码同包同目录,文件名以_test.go结尾;同包声明才能访问未导出标识符;go test默认不递归子目录,需用./...或显式路径;internal/等私有包的测试须置于对应目录内。
Go 的测试文件不是独立模块,go test 要求测试文件与被测源码在同一个包(package 声明一致)、同一个目录下。否则编译失败或无法访问未导出标识符。
utils.go 声明 package utils,测试文件必须也写 package utils,不能写 package utils_test(那是白盒测试的例外,见下条)_test.go 结尾,如 utils_test.go;否则 go test 会直接忽略_test 后缀的包名很多人误以为只要文件名带 _test.go 就能测私有成员,其实关键在包声明:只有当测试文件和源码**同包名**(比如都是 package main),才能直接调用未导出函数或读取未导出字段。
main_test.go 里写 package main_test → 无法访问 main 包里的 parseConfig()(小写)main_test.go 里写 package main → 可直接调用 parseConfig()
package xxx_test 是为“黑盒测试”设计的:只通过导出接口验证行为,隔离内部实现,适合集成测试或避免测试污染源码逻辑go test 默认只跑当前目录,不递归子目录执行 go test 时,它只查找当前目录下的 *_test.go 文件,并编译运行。子目录中的测试不会自动包含——哪怕子目录也有 go.mod 或同名包。
go test ./...(注意 ./... 是通配语法,不是路径拼接)go test ./storage/、go test ./handlers/auth/
internal/ 下的私有包),且测试文件在该目录内,必须用完整路径调用,go test 不会向上查找internal/ 和 cmd/ 下的测试位置internal/ 目录本意是限制外部导入,但测试文件放错位置会导致编译失败或权限绕过。
internal/utils/ 下的 helpers.go(package utils),其测试必须放在同一目录:即 internal/utils/utils_test.go,且声明 package utils
cmd/ 下——那样会因跨包无法访问 internal 中的类型,或触发 “use of internal package not allowed” 错误cmd/myapp/main.go 的测试也应放在 cmd/myapp/ 目录下,而不是根目录;否则 main 函数可能被多次定义(尤其当你用 go run . 和 go test 混合操作时)myproject/ ├── go.mod ├── main.go # package main ├── main_test.go # package main ← 可测未导出符号 ├── utils/ │ ├── helpers.go #package utils │ └── helpers_test.go # package utils ← 同包测试 └── internal/ └── db/ ├── connection.go # package db └── connection_test.go # package db ← 必须在这里,不能挪到根目录
实际项目里最容易漏掉的是子目录测试的显式路径调用,以及 internal/ 包测试文件的位置约束——这两处一错,go test 要么静默跳过,要么报错但提示模糊。