Golang:测试和工作目录

Jes*_*nds 38 unit-testing working-directory go

我正在为Go中的应用程序编写一些单元测试.但测试失败,因为它找不到配置文件.通常,二进制文件在路径下的工作目录中查找配置文件conf/*.conf.

我认为浏览到已经conf/运行的目录go test会解决它,但它仍然报告文件系统找不到指定的路径.

如何判断go test使用某个目录作为工作目录,以便实际执行测试?

小智 26

您可以使用调用者来获取当前测试源文件的路径,如下所示:

package sample

import (
    "testing"
    "runtime"
    "fmt"
)

func TestGetFilename(t *testing.T) {
    _, filename, _, _ := runtime.Caller(0)
    fmt.Println("Current test filename: " + filename)
}
Run Code Online (Sandbox Code Playgroud)


Eva*_*van 23

我不相信这是可能的.我没有找到明确说明这一点的文档,但我相信go test总是使用包目录(包含go源文件)作为工作目录.

  • 谢谢,这很烦人,但我想没有办法解决它.我可能会向Go项目添加一个错误报告/建议,或者在`go test`中添加`-w $ d`或`--working-dir = $ d`参数. (11认同)

One*_*One 10

虽然不太方便,但您始终可以将其作为命令行变量传递,例如:

package blah_test

import (
    "flag"
    "fmt"
    "os"
    "testing"
)

var (
    cwd_arg = flag.String("cwd", "", "set cwd")
)

func init() {
    flag.Parse()
    if *cwd_arg != "" {
        if err := os.Chdir(*cwd_arg); err != nil {
            fmt.Println("Chdir error:", err)
        }
    }
}

func TestBlah(t *testing.T) {
    t.Errorf("cwd: %+q", *cwd_arg)
}
Run Code Online (Sandbox Code Playgroud)

然后运行它:

?? oneofone@Oa [/tmp]                                                                                             
???? go test . -cwd="$PWD"
--- FAIL: TestBlah (0.00 seconds)
        blah_test.go:16: cwd: "/tmp"
Run Code Online (Sandbox Code Playgroud)


Joe*_*Joe 10

作为一种解决方法,我编译了测试并从当前目录执行测试.

go test -c && ./<mypackage>.test

或者,如果您需要可以使用的通用命令,则可以使用-o选项重命名测试文件.

go test -c -o xyz.test && ./xyz.test

  • 这对我来说就是最好的答案!我可以从我的二进制文件通常运行的同一目录运行我的测试。 (2认同)

小智 6

无论工作目录在哪里。它必须在您的项目Dir下。所以我的解决方案是

wd, _ := os.Getwd()
for !strings.HasSuffix(wd, "<yourProjectDirName>") {
    wd = filepath.Dir(wd)
}

raw, err := ioutil.ReadFile(fmt.Sprintf("%s/src/conf/conf.dev.json", wd))
Run Code Online (Sandbox Code Playgroud)

您的路径应始终从项目目录开始。每次您读取包中的文件并由main.go或另一个包单元测试访问。它将始终有效。

  • 这非常好,但如果您有使用“pkgname/cmd/pkgname”的(非常常见)模式,则不起作用。 (4认同)

小智 6

将 init 函数添加到测试包下的 *_test.go 中。测试包将在测试功能启动之前运行此功能。

func init() {
    _, filename, _, _ := runtime.Caller(0)
    // The ".." may change depending on you folder structure
    dir := path.Join(path.Dir(filename), "..")
    err := os.Chdir(dir)
    if err != nil {
        panic(err)
    }  
}
Run Code Online (Sandbox Code Playgroud)


小智 5

您可以使用os包

你想做这样的事情

    func TestMyFunction(t *testing.T) {
        os.Chdir("./path")

        //TEST FUNCTION

        os.Chdir("..")
    }
Run Code Online (Sandbox Code Playgroud)

os包中有几种可能性。