今天介绍下 Go1.17 中的特性:testing 包的一些变化。先看 Release Notes 关于 testing 变化的描述:
关于 shuffle 这个 flag,1.17 还未发布时,我就写过文章介绍:Go1.17这个新特性竟然是6年前提出来的。关于它的作用,记住关键一点:我们写测试时,测试之间别相互依赖,应该是独立的。
本文着重介绍另外一个特性:T.Setenv 和 B.Setenv。
从名字可以看出,这是设置环境变量用的。T 是单元测试,而 B 是基准测试。
你可能会说,os 包不是有 Setenv 吗?
os.Setenv 会影响当前进程的环境变量,而 T.Setenv 和 B.Setenv 只会影响当前测试函数的环境变量,不会对其他测试函数造成影响。通过它们,可以做到每个测试有自己的独立的 环境变量 。
Go 源码中,有不少测试文件使用了这个新功能,比如:
func TestImportVendor(t *testing.T) {
testenv.MustHaveGoBuild(t) // really must just have source
t.Setenv("GO111MODULE", "off")
ctxt := Default
wd, err := os.Getwd()
if err != nil {
t.Fatal(err)
}
ctxt.GOPATH = filepath.Join(wd, "testing/demo")
p, err := ctxt.Import("c/d", filepath.Join(ctxt.GOPATH, "src/a/b"), 0)
if err != nil {
t.Fatalf("cannot find vendored c/d from testdata src/a/b directory: %v", err)
}
want := "a/vendor/c/d"
if p.ImportPath != want {
t.Fatalf("Import succeeded but found %q, want %q", p.ImportPath, want)
}
}
具体源码:#L556。
如果你项目中的测试依赖环境变量,可以考虑使用这个新的函数。
注意:在 Parallel 测试中不能使用 Setenv。