5

From the testing docs:

"The package is built in a temporary directory so it does not interfere with the non-test installation."

So any code working with directories relative to the executable will not be present relative to Temp\go-build......

In other words, given the following:

.\helloplanet.go

.\planets\planetary.res

.\helloplanet_test.go

go test

Produces an exe in Temp\go-build... but it doesn't also re-create a planets\ subdir there, so any code in helloplanet.exe looking for planets\planetary.res of course won't find it.

How should one deal with this?

10 cls
  • 1,325
  • 2
  • 17
  • 31
  • You should be careful making any assumptions about the whereabouts of your executable. Your best guess is to access test files relative to $GOPATH in my opinion. – fuz Mar 17 '14 at 15:20
  • Have you tried anything yet? Your tests should be part of your package, and it shouldn't matter where it's built; the relative location is the same. – JimB Mar 17 '14 at 15:36
  • @FUZxxl It's not so much that I'm making assumptions about the whereabouts of the executable as I am about the subdir relative to the executable. – 10 cls Mar 17 '14 at 18:00
  • @JimB I have tried. Package is main. It wouldn't matter where the executable is placed by go test if subdirs were also copied to that location, but just running go test doesn't do that. It looks as though the -i flag might be useful if the subdir contained packaged .go code, but what if it's eg json files? – 10 cls Mar 17 '14 at 18:06
  • 2
    Even though the package is built in a temporary dir, the CWD is still the package directory when the test is executed. Do an `os.Getwd()`. – JimB Mar 17 '14 at 18:26
  • @JimB Ah. I was using: http://stackoverflow.com/questions/18537257/golang-how-to-get-the-directory-of-the-currently-running-file ? Want to make that an answer? – 10 cls Mar 17 '14 at 19:04

2 Answers2

9

Here's a solution that actually works. I found this buried in the jetbrains forum. Here's the answer that user Daniil Maslov came up with :


The trick is actually very simple and is to get the current executing and add .. to the project root.

Create a new directory and file like testing_init.go with the following content:

package testing_init

import (
  "os"
  "path"
  "runtime"
)

func init() {
  _, filename, _, _ := runtime.Caller(0)
  dir := path.Join(path.Dir(filename), "..")
  err := os.Chdir(dir)
  if err != nil {
    panic(err)
  }
}

After that, just import the package into any of the test files:


package main_test

import (
  _ "project/testing_init"
)

Now you can specify paths from the project root

1mike12
  • 2,946
  • 3
  • 27
  • 36
4

Though the test files are built in a temporary location, your working directory will be where you expect it. If you execute an os.Getwd() from within a test function, you'll see that your working directory is the package directory. This should work the same when running go test from within your package, or calling it with the full import path, as long as your package's location is in GOPATH.

In my packages, I often have a testadata directory, which is accessed via it's relative path, and have had no issues.

JimB
  • 104,193
  • 13
  • 262
  • 255
  • Thanks, that's great. I was using `filepath.Dir(os.Args[0])`. – 10 cls Mar 17 '14 at 19:17
  • 1
    Turns out though, that using os.Getwd() my program now needs to be run from the directory it's in ie if I'm in `~/` and run `./myprogdir/helloplanet` it doesn't see `myprogdir/planets/planetary.res`. That is, os.Getwd() gets the user's wd, not the program's wd. – 10 cls Mar 19 '14 at 12:40
  • @10cls: yes, that's what "working directory" means. I didn't mean to actually use Getwd() to find your data, just to show where the tests were running. How your program configures itself at runtime is usually different than for tests. – JimB Mar 19 '14 at 13:51
  • Ok, thanks. Too many hoops. I'll see if I can avoid testing from temp/go-build/ or something. – 10 cls Mar 19 '14 at 17:51