问题
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?
回答1:
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)
}
回答2:
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.
回答3:
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"
回答4:
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
回答5:
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.
回答6:
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.
回答7:
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
}
}
回答8:
I've had a similar problem and found the solution on this blog
Basically you can change the folder that the test is running using a similar function:
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)
}
}
来源:https://stackoverflow.com/questions/23847003/golang-tests-and-working-directory