Search code examples
unit-testinggoglobal-variablesmonkeypatching

Is Test_xxx func safe to access shared data in golang?


I'm confused about the golang unit test.

I have 2 Test_xxx funcs , like Test_1 and Test_2.
In Test_1, i will change a global variable , can Test_2 see the change?

Furthermore, if i use monkey patch instead of changing global var, will the other Test_xxx func perceive the patching?
i.e. do i have the necessary to cancel the func substitution using defer when Test_xxx returns?


Solution

  • Is Test_xxx func safe to access shared data in golang?

    The answer entirely depends on whether those test functions are allowed to run in parallel.

    By default, go test calls the test functions for a given package sequentially. However, if

    • you call t.Parallel() within both test functions, and
    • both functions access (write/write or write/read) the same global variable without any synchronization between them,

    you'll likely get a data race.


    To fix ideas, consider this simple test file:

    package main
    
    import (
        "fmt"
        "testing"
    )
    
    var count = 0
    
    func Test_1(t *testing.T) {
        t.Parallel()
        count++
        fmt.Println(count)
    }
    
    func Test_2(t *testing.T) {
        t.Parallel()
        count++
        fmt.Println(count)
    }
    

    If you run go test -race, the race detector will slap you on the wrist:

    ==================
    WARNING: DATA RACE
    --snip--
    FAIL
    exit status 1
    FAIL    whatever    0.730s
    

    This should convince you that you should be careful about handling global state in tests. The best thing to do is to avoid global state altogether, if you can. Alternatively, remember that care must be taken to synchronize access to global state as soon as you activate parallel test execution.