web-dev-qa-db-ja.com

Golang:テストと作業ディレクトリ

Goのアプリケーションの単体テストをいくつか書いています。ただし、構成ファイルが見つからないため、テストは失敗します。通常、バイナリはconf/*.confパスの下の作業ディレクトリで構成ファイルを探します。

conf/を含むディレクトリを参照してgo testを実行すると解決すると考えましたが、ファイルシステムが指定されたパスを見つけられないと報告しています。

テストを実際に実行できるように、特定のディレクトリを作業ディレクトリとして使用するようにgo testに指示するにはどうすればよいですか?

36
Jesse Brands

次のように、呼び出し元を使用して現在のテストソースファイルへのパスを取得できる場合があります。

package sample

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

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

これが可能だとは思わない。これを明示的に記述したドキュメントは見つかりませんでしたが、go testは常に作業ディレクトリとしてパッケージディレクトリ(goソースファイルを含む)を使用します。

22
Evan

あまり便利ではありませんが、いつでもコマンドライン変数として渡すことができます:

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"
10
OneOfOne

回避策として、テストをコンパイルし、現在のディレクトリからテストを実行します。

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

または、使用できる汎用コマンドが必要な場合は、-oオプションを使用してテストファイルの名前を変更できます。

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

10
Joe

作業ディレクトリがどこにあっても。プロジェクトのディレクトリの下にある必要があります。だから私の解決策は

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
Tecker.Yu

os package を使用できます。

あなたはこのようなことをしたいでしょう

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

        //TEST FUNCTION

        os.Chdir("..")
    }

Osパッケージにはいくつかの可能性があります。

4
amazingfly

アプリケーションの場所に環境変数を使用します。テストプログラムは一時的な場所から実行できるため、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
    }
}
0
kristianp