Table-Driven Testing in Go: Concepts, Examples, and Advanced Techniques
The article explains Go’s table‑driven testing pattern, showing how separating test data into a slice of structs simplifies test code, improves quality, and enables subtests, parallel execution, assertions, mocking, and custom templates, illustrated with a GetWeekDay example and advanced techniques.
This article introduces the table‑driven approach for writing unit tests in Go, explaining why it reduces the mental barrier of writing tests and improves code quality.
What is table‑driven? It is a data‑driven programming pattern that separates the mutable data from the stable processing flow by placing the data in a table (usually a slice of structs) instead of scattering it across multiple if‑else or switch branches.
Simple example : a function GetWeekDay(index int) string that maps an index to a weekday. The naïve implementation uses a long chain of if‑else statements, while the table‑driven version stores the weekday names in a slice and returns weekDays[index] .
Applying this pattern to tests, the article shows three styles:
Low‑quality tests with many separate test functions for each case.
Low‑quality tests using subtests ( t.Run ) but still duplicating code.
High‑quality table‑driven tests where a slice of test cases drives a loop that creates a subtest for each entry.
Example of a high‑quality table‑driven test:
func TestGetWeekDay(t *testing.T) {
type args struct { index int }
tests := []struct {
name string
args args
want string
}{
{name: "index=0", args: args{index: 0}, want: "Sunday"},
{name: "index=1", args: args{index: 1}, want: "Monday"},
// ... other cases ...
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
if got := GetWeekDay(tt.args.index); got != tt.want {
t.Errorf("GetWeekDay() = %v, want %v", got, tt.want)
}
})
}
}The article then explores advanced usages:
Parallel execution : add t.Parallel() inside each subtest and capture the loop variable with tt := tt to avoid the classic closure pitfall.
Assertions : replace manual if checks with assert.Equal(t, tt.want, got) from the testify library.
Mocking : use GoMock to mock external dependencies, showing how to define fields , a prepare function, and an assert function for each test case.
Custom templates : create a GoLand Live Template that generates a reusable table‑driven test skeleton with placeholders for fields, args, preparation, and assertions.
Finally, the article provides a brief author bio and a list of recommended reading links.
Tencent Cloud Developer
Official Tencent Cloud community account that brings together developers, shares practical tech insights, and fosters an influential tech exchange community.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.