Search code examples
unit-testinggoinitialization

Make Go tests independent from each other (mutation of global vars)


Given I run the following tests:

const unchanged = "unchanged"

var myField = unchanged

func TestChangeField1(t *testing.T) {
    if myField != unchanged {
        t.FailNow()
    }
    myField = "changed"
}

func TestChangeField2(t *testing.T) {
    if myField != unchanged {
        t.FailNow()
    }
    myField = "changed"
}

The second test will fail because the variable has already been changed in the other test.

I know there are workarounds like using a test suite which offers hooks to reset this value to the initial state between the tests. But first this means some overhead, and second I feel that the whole behavior is surprising, so I can't really be sure that everybody in my project remembers that and complies.

Is there is a more straight-forward solution for go test, like a flag I haven't found yet?


Solution

  • @JimB mentioned this in the comments but if you need to run clean up after a test case you can register functions that run after each test with t.Cleanup.

    package main_test
    
    import (
        "testing"
    )
    
    const Default = "default"
    const SomethingElse = "something else"
    
    var someVar = Default
    
    func TestOne(t *testing.T) {
        t.Cleanup(resetState)
        if someVar != Default {
            t.FailNow()
        }
        someVar = SomethingElse
    }
    
    func TestTwo(t *testing.T) {
        t.Cleanup(resetState)
        if someVar != Default {
            t.FailNow()
        }
        someVar = SomethingElse
    }
    
    func resetState() {
        someVar = Default
    }