优先用testdata/目录存放原始测试数据,动态生成数据才封装进internal/testutil或xxx_test包;TestMain不可用于预加载共享数据;表驱动测试用只读包级变量定义用例;跨包复用需提取到internal/testdata。

测试数据该定义在 testutil 包还是直接放 testdata/ 目录?
优先用 testdata/ 目录存放原始测试数据(如 JSON 文件、CSV 样本、SQL dump),而非硬编码在 Go 源文件里。这样能避免污染测试逻辑,也方便人工校验和复用。
如果数据需要动态生成或带逻辑(比如构造含时间戳的 JWT、随机但符合规则的邮箱),才考虑封装进 testutil 包——但这个包必须是 internal/testutil 或 xxx_test 后缀,防止被外部模块意外 import。
-
testdata/下的文件不会被go build打包,仅测试时可读(os.ReadFile("testdata/config.json")) - 不要在
testdata/里放 Go 源文件(如testdata/fixtures.go),Go 测试工具链不识别这种“伪测试依赖” - 路径写相对路径即可,
testing.TB的TempDir()和testutil工具函数都默认基于当前测试文件所在目录解析
TestMain 能不能用来预加载共享数据?
不能。Go 的 TestMain 是包级入口,只运行一次,但它无法安全共享状态给并行测试(t.Parallel()),且一旦某个测试 panic,后续测试可能拿到损坏的全局变量。
真正安全的共享方式是「惰性初始化 + sync.Once」配合包级变量,或者更推荐:每个测试自己调用工厂函数获取干净副本。
func newSampleUser() User {
return User{
ID: 123,
Name: "alice",
Email: "alice@example.com",
Created: time.Now().UTC().Truncate(time.Second),
}
}
func TestCreateUser(t *testing.T) {
u := newSampleUser()
// 修改字段仅影响当前测试
u.Email = "test-" + t.Name() + "@example.com"
// ...
}
表驱动测试中如何复用输入输出对?
把测试用例定义成包级变量(类型为切片),而不是在每个 TestXxx 函数里重复声明。注意:这些变量必须是只读结构(如 []struct{in, want string}),不能含指针或 map 等可变内嵌字段,否则多个测试并发修改会互相干扰。
家电公司网站源码是一个以米拓为核心进行开发的家电商城网站模板,程序采用metinfo5.3.9 UTF8进行编码,软件包含完整栏目与数据。安装方法:解压上传到空间,访问域名进行安装,安装好后,到后台-安全与效率-数据备份还原,恢复好数据后到设置-基本信息和外观-电脑把网站名称什么的改为自己的即可。默认后台账号:admin 密码:132456注意:如本地测试中127.0.0.1无法正常使用,请换成l
- 用
var testCases = []struct{...}{...}定义,放在xxx_test.go顶部 - 如果某个测试需修改 case 数据,先
copy再改,例如:c := testCase[i]; c.in = "modified" - 避免在 case 中直接引用
time.Now()或rand.Intn()—— 这会让测试不可重现;改用固定种子或注入时间接口
跨包复用测试数据时为什么总报 “undefined”?
因为 Go 不允许非 _test 包直接 import xxx_test 包。常见错误是想让 pkgA 的测试代码复用 pkgB 的 fixture.NewDB(),结果编译失败。
正确做法只有两个:
- 把通用 fixture 提取到
internal/testdata(不是testdata/!),并确保它不 import 任何业务包(否则破坏 internal 封装) - 用
//go:build ignore+go run临时脚本生成测试数据,不走 import 机制
别试图用符号链接或 replace 指向测试文件——go test 会跳过非 *_test.go 文件,且模块校验会失败。









