当我运行“go test”时,我想使用不同的配置文件。我如何在我的代码中知道我是在测试上下文还是正常上下文中运行?是否有某种环境变量要检查?
10 回答
测试包在加载时会修改全局环境:它注册了很多命令行标志。因此,我们可以检查这些标志是否已注册:
func init() {
if flag.Lookup("test.v") == nil {
fmt.Println("normal run")
} else {
fmt.Println("run under go test")
}
}
由于该flag.Lookup("test.v")
方法对我不起作用,我想分享我自己的解决方案:
strings.HasSuffix(os.Args[0], ".test")
或者
strings.Contains(os.Args[0], "/_test/")
两者似乎都有效。
一种可能性是使用构建约束。如果你运行go test
为:
go test -tags testing pkgname
然后,您可以使用该标签来选择哪些文件将包含在您的包的标准构建中,哪些文件将用于测试。
如果您将标准配置放在自己的文件中,则在顶部添加一行如下所示将确保它不用于测试:
// +build !testing
然后,您可以将测试配置包含在其中一个文件中,或者包含在需要设置标记*_test.go
的其他文件中。testing
代码示例会有所帮助。但是从您的问题来看,听起来您已经在某处硬编码了配置文件的路径,而您可能想将其传递进去。
更改您正在测试的函数以获取定义配置文件的参数,然后在您的测试代码中传递与您在非测试代码中使用的路径不同的路径。在测试与生产时,您的代码采用不同的路径是不好的做法。
该flag.Lookup("test.v") == nil
方法似乎有效,但我建议使用TestMain,它专门设计用于允许对测试进行特定设置和拆卸。如果您在要测试的包中包含此方法,它将在您的单独测试之前调用,因此您可以在调用 m.Run() 之前设置全局标志或执行您想要执行的任何测试特定配置,如下所示
func TestMain(m *testing.M) {
// test context initialization here
os.Exit(m.Run())
}
PS:这实际上是@calvin-sugianto 建议的,除了杜松子酒与它无关
该flag.Lookup("test.v")
解决方案对我也不起作用(转到 1.13),而且我有很多服务要维护,并且func TestMain(m *testing.M)
在每个服务中都使用该解决方案是不可行的。由于所有服务共享一个公共库,我提出了以下解决方案:
func isInTests() bool {
for _, arg := range os.Args {
if strings.HasPrefix(arg, "-test.v=") {
return true
}
}
return false
}
这类似于flag.Lookup("test.v")
解决方案,因为我们检查是否-test.v
存在。
编辑:根据@mh-cbon 评论更新了代码
我是 golang 的新手,flag.Lookup("test.v")
对我不起作用,所以我找到了通过在 init() 中设置 ENV 变量来识别上下文是否正在测试或正常的方法。
如果您有测试文件,例如 abc.text.go,请将环境变量“GO_ENV”设置为 init() 中的测试。
func init() {
os.Setenv("GO_ENV", "testing")
}
无论您想知道上下文,请使用 os.Getenv("GO_ENV")
abc.go
if os.Getenv("GO_ENV") == "testing" {
} else {
}
与 Pram 的回答类似,我可能会在您运行测试时设置一个环境变量。
生成文件
test:
ENV=testing go test ./...
main.go
env := os.Getenv("ENV")
Garrett 的更强大的解决方案是:
func init() {
if v := flag.Lookup("test.v"); v == nil || v.Value.String() != "true" {
fmt.Println("normal run")
} else {
fmt.Println("run under go test")
}
}
如果您尝试检测文件是否通过“go run”与可执行文件运行,此函数将检查目录是否包含“/Temp/go-build”(还检查 \ 是否支持 Windows)
if strings.Index(os.Args[0], "/Temp/go-build") != -1 || strings.Index(os.Args[0], "\\Temp\\go-build") != -1 {
// ran with go run
} else {
// ran as executable file
}