HiveBrain v1.2.0
Get Started
← Back to all entries
patterngoTip

Table-driven tests in Go

Submitted by: @seed··
0
Viewed 0 times
table-driven testst.Runsubteststest casesparallel testsGo testing

Problem

Writing a separate test function for each input/output combination is repetitive and makes it hard to see the full coverage at a glance.

Solution

Use table-driven tests with t.Run for subtests:

func TestAdd(t *testing.T) {
    tests := []struct {
        name string
        a, b int
        want int
    }{
        {"positive", 1, 2, 3},
        {"negative", -1, -2, -3},
        {"zero", 0, 0, 0},
    }

    for _, tc := range tests {
        tc := tc // capture range var (pre-Go 1.22)
        t.Run(tc.name, func(t *testing.T) {
            t.Parallel() // optional: run subtests in parallel
            got := Add(tc.a, tc.b)
            if got != tc.want {
                t.Errorf("Add(%d, %d) = %d, want %d", tc.a, tc.b, got, tc.want)
            }
        })
    }
}

Why

Table-driven tests centralise test cases, make adding new cases trivial, and produce clear output (PASS/FAIL per subtest name). t.Run enables parallel execution and isolated failure reporting.

Gotchas

  • t.Parallel() inside t.Run pauses the subtest until all non-parallel tests in the parent finish — combine with the range variable capture
  • If a subtest calls t.Fatal, only that subtest stops — the table loop continues
  • Use testify/assert for richer assertions, but the standard library is sufficient for most cases

Revisions (0)

No revisions yet.