2014-05-24 14 views
22

Sto scrivendo alcuni test di unità per la mia applicazione in Go. I test falliscono tuttavia perché non riesce a trovare i file di configurazione. Normalmente il binario cerca i file di configurazione nella directory di lavoro sotto il percorso conf/*.conf.Golang: test e directory di lavoro

Ho immaginato che la navigazione nella directory che ha conf/ e in esecuzione go test in esso lo risolva, ma continua a segnalare che il file system non riesce a trovare il percorso specificato.

Come posso dire a go test di utilizzare una determinata directory come directory di lavoro in modo che i test possano essere effettivamente eseguiti?

+2

Se i test dell'unità dipendono dalla configurazione, non si tratta di test unitari. – Flimzy

risposta

17

Non credo sia possibile. Non sono stato in grado di trovare la documentazione che lo dichiara esplicitamente, ma credo che go test utilizzi sempre la directory del pacchetto (contenente i file di origine go) come directory di lavoro.

+6

Grazie, è molto fastidioso, ma suppongo che non ci sia modo di aggirarlo. Probabilmente aggiungerò un bug report/suggerimento al progetto Go per aggiungere forse un parametro '-w $ d' o' --working-dir = $ d' a 'go test'. –

8

Mentre non molto comodo, si può sempre passare come una variabile della riga di comando, ad esempio:

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

quindi eseguirlo come:

┌─ [email protected] [/tmp]                        
└──➜ go test . -cwd="$PWD" 
--- FAIL: TestBlah (0.00 seconds) 
     blah_test.go:16: cwd: "/tmp" 
+0

Questa è una buona idea. Sono curioso però, quale prompt dei comandi è che stai usando? –

+0

Sto usando pesce, la funzione specifica per mostrare il prompt è @ https://github.com/OneOfOne/etc-fish/blob/master/functions/fish_prompt.fish – OneOfOne

+0

Abbastanza impressionante, grazie mille. –

10

si può essere in grado di utilizzare il chiamante per ottenere il percorso del file dell'origine test corrente, ad esempio:

package sample 

import (
    "testing" 
    "runtime" 
) 

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

Questa dovrebbe essere la risposta accettata. – imgen

+0

D'accordo, questo è un modo molto carino per farlo. Combina con la funzione Dir dal pacchetto "percorso/percorso file" per creare un percorso relativo alla cartella del file di input input. – Yobert

5

Come soluzione temporanea, ho compilato il test e eseguire il test dalla directory corrente.

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

Oppure, se si vuole un comando generico che è possibile utilizzare, è possibile rinominare il file di prova con -o opzione.

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

2

È possibile utilizzare il os package.

si vorrebbe fare qualcosa di simile

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

     //TEST FUNCTION 

     os.Chdir("..") 
    } 

Ci sono diverse possibilità nel pacchetto del sistema operativo.

+1

Sfortunatamente, questo non sembra funzionare quando il codice sorgente contiene chiamate '* template.Must (...)' per compilare template HTML. – Ralph

0

Vorrei utilizzare una variabile di ambiente per il percorso dell'applicazione. Sembra essere il modo migliore quando si eseguono gli strumenti di go, dato che i programmi di test possono essere eseguiti da una posizione temporanea.

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

Non importa dove si trova la directory di lavoro. Deve essere sotto il tuo progetto Dir. Quindi la mia soluzione è

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

Il tuo percorso dovrebbe sempre iniziare dal tuo progetto Dir. Ogni volta che leggi il file in un pacchetto e accedi a main.go o al tuo altro test dell'unità pacchetto. Funzionerà sempre.