Golang:测试和工作目录

时间:2014-05-24 15:58:09

标签: unit-testing go working-directory

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

我认为浏览到conf/并在其中运行go test的目录可以解决它,但它仍然报告文件系统无法找到指定的路径。

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

10 个答案:

答案 0 :(得分:22)

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

答案 1 :(得分:22)

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

package sample

import (
    "testing"
    "runtime"
)

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

答案 2 :(得分: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)
}

然后运行它:

┌─ oneofone@Oa [/tmp]                                                                                             
└──➜ go test . -cwd="$PWD"
--- FAIL: TestBlah (0.00 seconds)
        blah_test.go:16: cwd: "/tmp"

答案 3 :(得分:10)

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

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

或者,如果您想要一个可以使用的通用命令,可以使用-o选项重命名测试文件。

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

答案 4 :(得分:4)

您可以使用os package

你会想要做这样的事情

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

        //TEST FUNCTION

        os.Chdir("..")
    }

os包中有几种可能性。

答案 5 :(得分:4)

无论工作目录在哪里。它必须在您的项目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))

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

答案 6 :(得分:3)

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

func init() {
    os.Chdir("..")
}

答案 7 :(得分:1)

我知道这是一个古老的问题,但是我在尝试对测试使用数据库迁移时遇到了同样的问题,也许此解决方案可以帮助某人。

由于没有获取项目目录的本地方法,因此您可以识别一些文件或目录,这些文件或目录仅位于项目的根目录中(在我的情况下,它是相对目录 database / migrations < / strong>)。一旦有了这个唯一的相对目录,就可以具有如下所示的功能来获取项目的根目录。它只是获取当前的工作目录(假设它位于项目的目录中),并一直向上导航,直到找到一个目录,该目录具有您知道的相对目录在项目的根目录中:

func FindMyRootDir() string {
    workingDirectory, err := os.Getwd()

    if err != nil {
        panic(err)
    }

    lastDir := workingDirectory
    myUniqueRelativePath := "database/migrations"

    for {
        currentPath := fmt.Sprintf("%s/%s", lastDir, myUniqueRelativePath)

        fi, err := os.Stat(currentPath)

        if err == nil {
            switch mode := fi.Mode(); {
            case mode.IsDir():
                return currentPath
            }
        }

        newDir := filepath.Dir(lastDir)

        // Ooops, we couldn't find the root dir. Check that your "myUniqueRelativePath" really exists

        if newDir == "/" || newDir == lastDir {
            return ""
        }

        lastDir = newDir
    }
}

当然,这不是最漂亮的解决方案,但它可以工作。

答案 8 :(得分:0)

我会使用环境变量来表示您的应用程序的位置。这似乎是运行go工具的最佳方式,因为测试程序可以从临时位置运行。

// get home dir of app, use MYAPPHOME env var if present, else executable dir.
func exeDir() string {
    dir, exists := os.LookupEnv("MYAPPHOME")
    if exists {
        return dir
    } else {
        ex, err := os.Executable()
        if err != nil {
            panic(err)
        }
        exPath := path.Dir(ex)
        return exPath
    }
}

答案 9 :(得分:0)

我遇到了类似的问题,找到了解决方法on this blog

基本上,您可以使用类似的功能来更改测试运行的文件夹:

package main

import (
    "os"
    "path"
    "runtime"
)

func MakeFunctionRunOnRootFolder() {
    _, 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)
    }
}