brandur.org

Testing Go packages from project root

By default, running go test executes a package’s tests with the current working directory set to that package’s path. This is fine for single-package projects, but for a more complex one, it’s often useful to execute tests from a single root directory so to simplify access to common test resources or other files on-disk.

I’ve been using a simple trick involving Go’s runtime package to accomplish this feat. Given a project package/directory hierarchy like this one:

github.com/brandur/project/
  + cmd/
    + executable/
      - main.go
  + testing/
    - testing.go

In testing.go:

package testing

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

The filename returned by runtime.Caller(0) will be the one currently executing; testing.go in this case. Join the result to .. gets the project’s root, and a call to os.Chdir takes the running program there.

Then from any other package in the project, import the testing package with a blank identifier, which will run its init function, but exclude its exported symbols:

package main_test

import (
	_ "github.com/brandur/project/testing"
)

Did I make a mistake? Please consider sending a pull request.