来自测试文档:
“该包构建在临时目录中,因此不会干扰非测试安装。”
因此,任何使用与可执行文件相关的目录的代码都不会相对于 Temp\go-build......
换句话说,考虑到以下情况:
.\helloplanet.go
.\行星\planetary.res
.\helloplanet_test.go
go test
Run Code Online (Sandbox Code Playgroud)
在 Temp\go-build... 中生成一个 exe 文件,但它不会在那里重新创建一个planets\ 子目录,因此 helloplanet.exe 中寻找planets\planetary.res 的任何代码当然不会找到它。
应该如何处理这个问题呢?
这是一个实际有效的解决方案。我发现这个埋在jetbrains论坛里。以下是用户 Daniil Maslov 给出的答案:
技巧实际上非常简单,就是获取当前执行并添加..到项目根目录。
创建一个新目录和文件,testing_init.go内容如下:
package testing_init
import (
"os"
"path"
"runtime"
)
func init() {
_, filename, _, _ := runtime.Caller(0)
dir := path.Join(path.Dir(filename), "..")
err := os.Chdir(dir)
if err != nil {
panic(err)
}
}
Run Code Online (Sandbox Code Playgroud)
之后,只需将包导入到任何测试文件中:
package main_test
import (
_ "project/testing_init"
)
Run Code Online (Sandbox Code Playgroud)
现在您可以指定项目根目录的路径
尽管测试文件是在临时位置构建的,但您的工作目录将位于您期望的位置。如果您在测试函数中执行os.Getwd(),您将看到您的工作目录是包目录。go test只要包的位置位于 GOPATH 中,从包内运行或使用完整导入路径调用它时,这应该是相同的。
在我的包中,我经常有一个 testadata 目录,可以通过其相对路径访问该目录,并且没有任何问题。