Go – setup and teardown for each test using std testing package

gounit testing

I am using go "testing" package. Running my tests like below.

func TestMain(m *testing.M) {

   ...
   // Setup
   os.Exit(m.Run())
   // Teardown
}

This will run a setup before any test is run, and a teardown after all tests are complete. And I do need this, as the setup sets the DB up. But also, I need, and yet to find out a way to run a per-test setup/teardown. For the unit tests I am running, I would like to clear the DB before every test, so that there are no issues with the content of the DB causing unexpected behavior.

Best Answer

Update for Go 1.14 (Q1 2020)

The testing package now supports cleanup functions, called after a test or benchmark has finished, by calling T.Cleanup or B.Cleanup respectively. Example,

func TestFunction(t *testing.T) {
    // setup code
    // sub-tests
    t.Run() 
    t.Run() 
    ...
    // cleanup
    t.Cleanup(func(){
        //tear-down code
    })
}

Here, t.Cleanup runs after the test and all its sub-tests are complete.


Original answer (Feb. 2017)
As shown in the article "Go unit test setup and teardown" from Kare Nuorteva, you could use a setup function which returns... a teardown function to you defer.

See this gist:

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

The setup function is in charge of defining and returning the teardown one.

For each test, for instance in a table-driven test scenario:

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