How can I do test setup using the testing package in Go

How can I do overall test setup processing which sets the stage for all the tests when using the testing package?

As an example in Nunit there is a [SetUp] attribute.

[TestFixture]
public class SuccessTests
{
  [SetUp] public void Init()
  { /* Load test data */ }
}

Starting with Go 1.4 you can implement setup/teardown (no need to copy your functions before/after each test). The documentation is outlined here in the Main section:

TestMain runs in the main goroutine and can do whatever setup and teardown is necessary around a call to m.Run. It should then call os.Exit with the result of m.Run

It took me some time to figure out that this means that if a test contains a function func TestMain(m *testing.M) then this function will be called instead of running the test. And in this function I can define how the tests will run. For example I can implement global setup and teardown:

func TestMain(m *testing.M) {
    setup()
    code := m.Run() 
    shutdown()
    os.Exit(code)
}

A couple of other examples can be found here.

The TestMain feature added to Go’s testing framework in the latest release is a simple solution for several testing use cases. TestMain provides a global hook to perform setup and shutdown, control the testing environment, run different code in a child process, or check for resources leaked by test code. Most packages will not need a TestMain, but it is a welcome addition for those times when it is needed.


This can be achieved by putting a init() function in the myfile_test.go file. This will be run before the init() function.

// myfile_test.go
package main

func init() {
     /* load test data */
}

The myfile_test.init() will be called before the package init() function.


Given a simple function to unit test:

package math

func Sum(a, b int) int {
    return a + b
}

You can test it with a setup function that returns teardown function. And after calling setup() you can make a deferred call to teardown().

package math

import "testing"

func setupTestCase(t *testing.T) func(t *testing.T) {
    t.Log("setup test case")
    return func(t *testing.T) {
        t.Log("teardown test case")
    }
}

func setupSubTest(t *testing.T) func(t *testing.T) {
    t.Log("setup sub test")
    return func(t *testing.T) {
        t.Log("teardown sub test")
    }
}

func TestAddition(t *testing.T) {
    cases := []struct {
        name     string
        a        int
        b        int
        expected int
    }{
        {"add", 2, 2, 4},
        {"minus", 0, -2, -2},
        {"zero", 0, 0, 0},
    }

    teardownTestCase := setupTestCase(t)
    defer teardownTestCase(t)

    for _, tc := range cases {
        t.Run(tc.name, func(t *testing.T) {
            teardownSubTest := setupSubTest(t)
            defer teardownSubTest(t)

            result := Sum(tc.a, tc.b)
            if result != tc.expected {
                t.Fatalf("expected sum %v, but got %v", tc.expected, result)
            }
        })
    }
}

Go testing tool will report the logging statements in the shell console:

% go test -v
=== RUN   TestAddition
=== RUN   TestAddition/add
=== RUN   TestAddition/minus
=== RUN   TestAddition/zero
--- PASS: TestAddition (0.00s)
    math_test.go:6: setup test case
    --- PASS: TestAddition/add (0.00s)
        math_test.go:13: setup sub test
        math_test.go:15: teardown sub test
    --- PASS: TestAddition/minus (0.00s)
        math_test.go:13: setup sub test
        math_test.go:15: teardown sub test
    --- PASS: TestAddition/zero (0.00s)
        math_test.go:13: setup sub test
        math_test.go:15: teardown sub test
    math_test.go:8: teardown test case
PASS
ok      github.com/kare/go-unit-test-setup-teardown 0.010s
% 

You can pass some additional parameters to setup/teardown with this approach.


Typically, tests in go aren't written in the same style as other languages. Often, there's relatively fewer test functions, but each contains a table-driven set of test cases. See this article written by one of the Go team.

With a table-driven test, you simply put any setup code before the loop that executes the individual test-cases specified in the table, and put any cleanup code afterwards.

If you still have shared setup code between test functions, you can extract the shared setup code into a function, and use a sync.Once if it's important that it's executed exactly once (or as another answer suggests, use init(), but this has the disadvantage that the setup will be done even if the test cases aren't run (perhaps because you've limited the test cases by using go test -run <regexp>.)

I'd say if you think you need shared setup between different tests that gets executed exactly once you should have a think if you really need it, and if a table-driven test wouldn't be better.


The Go testing framework doesn't have anything equivalent to NUnit's SetUp attribute (marking a function to be called before each test in the suite). There are a few options though:

  1. Simply call your SetUp function from each test where it is needed.

  2. Use an extension to Go's testing framework that implements xUnit paradigms and concepts. Three strong options come to mind:

    • gocheck
    • testify
    • gunit

Each of these libraries encourage you to organize your tests into suites/fixtures similar to other xUnit frameworks, and will call the setup methods on the suite/fixture type before each of the Test* methods.