Golang:测试和工作目录

I'm writing some unit tests for my application in Go. The tests fail however because it cannot find the configuration files. Normally the binary looks for the configuration files in the working directory under the path conf/*.conf.

I figured that browsing to the directory that has conf/ and running go test in it would solve it, but it still reports that the file system cannot find the path specified.

How can I tell go test to use a certain directory as the working directory so that the tests may actually be executed?

You may be able to use the Caller to get the path to the current test source file, like this:

package sample

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

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

I do not believe this is possible. I have not been able to find documentation stating this explicitly, but I believe go test always uses the package directory (containing the go source files) as the working directory.

While not really convenient, you can always pass it as a command line variable, for example :

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)
}

Then run it like :

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

As a workaround, I compiled the test and execute the test from the current directory.

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

Or, if you want a generic command that you can use, you can rename the test file with -o option.

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

You can use the os package.

You would want to do something like this

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

        //TEST FUNCTION

        os.Chdir("..")
    }

There are several possibilities in the os package.

I would use an Environment Variable for the location of your application. It seems to be the best way when running go tools, as test programs can be run from a temporary location.

// 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
    }
}

No matter where the work directory is. It must be under your project Dir. So my solution is

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))

Your path should always start from your project Dir. Every time you read the file in a package and accessed by main.go or your another package unit test. It will always work.

asdasd