Table-Driven Tests
Parameterized tests with subtests
Table-Driven Tests is a free Go Academy lesson on CoddyKit — lesson 2 of 4. You can read the complete lesson below for free — then practise it hands-on in the browser with a built-in code editor and a 24/7 AI tutor. It is part of the Go Academy learning path, one of 4 lessons in the course, and your progress syncs across the web and the CoddyKit app.
What are table-driven tests?
Table-driven tests define a slice of test cases (inputs and expected outputs) and loop over them with a single test body. They reduce duplication and make adding cases trivial.
Basic pattern
Define a struct for each case, loop with t.Run, and report failures with the case name:
tests := []struct {
name string
input int
want int
}{
{"zero", 0, 0},
{"positive", 3, 9},
{"negative", -2, 4},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
got := Square(tt.input)
if got != tt.want {
t.Errorf("Square(%d) = %d; want %d", tt.input, got, tt.want)
}
})
}Anonymous struct slice
Use an anonymous struct for the test case type — it keeps the case definition close to the test and avoids naming a one-use type.
Including error cases
Add a wantErr bool field to test that functions return errors in the expected scenarios:
{"invalid input", -1, 0, true},
// in the loop:
if (err != nil) != tt.wantErr {
t.Errorf("wantErr %v, got err %v", tt.wantErr, err)
}Naming subtests
A descriptive name field makes failures self-explanatory. You can run a specific case with -run TestFunc/case_name.
t.Run parallel subtests
Mark each subtest parallel and capture the loop variable to run cases concurrently (important when tests are I/O-bound).
for _, tt := range tests {
tt := tt // capture
t.Run(tt.name, func(t *testing.T) {
t.Parallel()
// ...
})
}Shared setup per case
Use tt.setup function fields to allow per-case setup without duplicating boilerplate:
type tc struct {
setup func() *DB
input string
want int
}Keeping cases readable
If cases grow large, define them as named variables or load them from testdata files. Keep the table compact — one line per case when possible.
Testing multiple outputs
Table test functions that return multiple values by adding a field per output:
type tc struct {
input string
wantVal int
wantErr bool
}Testify assert in tables
Use github.com/stretchr/testify/assert inside table tests for readable assertions without verbose if/t.Errorf blocks.
assert.Equal(t, tt.want, got, tt.name)Documenting with cases
The table of cases serves as living documentation. Future developers read it to understand all supported inputs and edge cases at a glance.
Quick Check
Why do you capture the loop variable (tt := tt) before t.Parallel in table-driven tests?
Recap: Table-Driven Tests
Key points:
- Slice of structs covering inputs, expected outputs, and error flag
- Loop with t.Run for named, independent subtests
- Capture loop variable (tt := tt) before t.Parallel
- Cases serve as living documentation of supported behaviours
Frequently asked questions
Is the “Table-Driven Tests” lesson free?
Yes — the full text of “Table-Driven Tests” is free to read here on the web, and the Go Academy course includes 4 lessons in total. To practise it interactively (a built-in code editor and a 24/7 AI tutor) and unlock the rest of the Go Academy course, upgrade to CoddyKit PRO.
What will I learn in “Table-Driven Tests”?
Parameterized tests with subtests You practise Go Academy with hands-on code you run directly in the browser, and a 24/7 AI tutor answers your questions as you work through the lesson.
Do I need any experience to start Go Academy?
No prior experience is required. Go Academy on CoddyKit is structured for beginners through advanced learners; this is — lesson 2 of 4, so you can start here or from the beginning and move at your own pace.
How long does the “Table-Driven Tests” lesson take?
Most CoddyKit lessons take about 5–10 minutes. Each one is bite-sized and interactive, so you make steady progress and pick up exactly where you left off across the web and the app.
Can I write and run code in this Go Academy lesson?
Yes. Every Go Academy lesson includes a built-in code editor, so you write and run real code right in your browser and get instant AI feedback — no local setup required.