Golang: tests en werkmap

Ik ben enkele unit-tests aan het schrijven voor mijn toepassing in Go. De tests mislukken echter omdat het de configuratiebestanden niet kan vinden. Normaal zoekt het binaire bestand naar de configuratiebestanden in de werkmap onder het pad conf/*.conf.

Ik dacht dat browsen naar de map met conf/en het uitvoeren van go testhet zou oplossen, maar het meldt nog steeds dat het bestandssysteem het pad niet kan vinden gespecificeerd.

Hoe kan ik go testvertellen dat ik een bepaalde directory als werkdirectory moet gebruiken, zodat de tests daadwerkelijk kunnen worden uitgevoerd?


Antwoord 1, autoriteit 100%

Misschien kunt u de beller gebruiken om het pad naar het huidige testbronbestand te krijgen, zoals dit:

package sample
import (
    "testing"
    "runtime"
    "fmt"
)
func TestGetFilename(t *testing.T) {
    _, filename, _, _ := runtime.Caller(0)
    t.Logf("Current test filename: %s", filename)
}

Antwoord 2, autoriteit 57%

Ik geloof niet dat dit mogelijk is. Ik heb geen documentatie kunnen vinden waarin dit expliciet wordt vermeld, maar ik geloof dat go testaltijd de pakketdirectory (met de go-bronbestanden) als werkdirectory gebruikt.


Antwoord 3, autoriteit 33%

Als tijdelijke oplossing heb ik de test gecompileerd en de test uitgevoerd vanuit de huidige map.

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

Of, als u een generieke opdracht wilt die u kunt gebruiken, kunt u het testbestand hernoemen met de optie -o.

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


Antwoord 4, autoriteit 22%

Hoewel niet echt handig, je kunt het altijd doorgeven als een opdrachtregelvariabele, bijvoorbeeld:

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

Voer het dan uit als:

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

Antwoord 5, autoriteit 20%

Het maakt niet uit waar de werkmap zich bevindt. Het moet onder uw project Dir. Dus mijn oplossing 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))

Je pad moet altijd beginnen bij je project Dir. Elke keer dat u het bestand in een pakket leest en geopend wordt door main.go of uw andere pakketeenheidstest. Het zal altijd werken.


Antwoord 6, autoriteit 18%

Je kunt het os-pakketgebruiken.

Je zou zoiets willen doen

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

Er zijn verschillende mogelijkheden in het os-pakket.


Antwoord 7, autoriteit 14%

Om de init-functie toe te voegen aan *_test.go onder uw testpakket.
Het testpakket zal deze functie uitvoeren voordat de testfunctie start.

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

Antwoord 8, autoriteit 2%

Ik heb een soortgelijk probleem gehad en vond de oplossing op deze blog

In principe kunt u de map waarin de test wordt uitgevoerd wijzigen met een vergelijkbare functie:

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

Antwoord 9

Ik zou een omgevingsvariabele gebruiken voor de locatie van uw toepassing. Het lijkt de beste manier te zijn bij het uitvoeren van go-tools, omdat testprogramma’s vanaf een tijdelijke locatie kunnen worden uitgevoerd.

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

Antwoord 10

Het is een gangbare praktijk in Go om testarmaturen in hetzelfde pakketin de map testdatate plaatsen.

Enkele voorbeelden uit de standaardbibliotheek:

Ook is er een postvan Dave Cheney, waar hij de volgende code voorstelt:

f, err := os.Open("testdata/somefixture.json")

Other episodes