Skip to main content

One Test, Many Cases

Most functions need the same check for many inputs: normal values, negative values, zero, edge cases. Copying the test five times makes five places to maintain.

The Go way is a table-driven test: put the cases into a slice of structs — each case holds a name, the inputs and the expected output — and run one loop over them.

Adding a new case becomes one new line in the table. This is the most common test pattern you will see in real Go code.


The Table

The table is an anonymous struct slice, defined right inside the test. Each entry is one case: a name (for the failure message), the inputs, and the expected result.

The loop calls the function once per case and reports each mismatch with t.Errorf — so every broken case shows up, not just the first.

Four cases in one table

Four cases, one loop, one check. All pass here. To test a fifth situation you would add one line to the table — the loop stays untouched.

Prompt
Write a Go table-driven test for an Add function: a slice of anonymous structs with a case name, two int inputs and the expected result, covering one plus one, positive and negative, both negative, and zeros. Loop over the table and report mismatches with t.Errorf including the case name. Show the go test -v output.
Output: Go test file and captured go test output
Four cases in one table

Subtests with t.Run

t.Run(name, func(t *testing.T) { … }) turns each table case into its own subtest. The case names now appear in the go test -v output, like TestAdd/both_negative (spaces become underscores).

Each subtest passes or fails on its own, which makes a broken case easy to spot in a long table.

Every case gets a name

The same table, wrapped in t.Run. The verbose output now lists all four cases separately — you can see exactly which cases ran and passed.

Prompt
Write the same table-driven Go test for Add, but run each case as a subtest with t.Run using the case name, so every case appears separately in the verbose output. Show the go test -v output with all subtest lines.
Output: Go test file and captured go test output

Run One Case Alone

Subtests can be selected from the command line with -run, using TestName/subtest_name:

go test -v -run "TestAdd/both_negative"

Only the matching subtest runs. This is perfect while fixing one broken case: rerun just that case until it is green, then run everything again.

Filter with -run

The same file as above, run with -run "TestAdd/both_negative". Only one of the four cases executes — the others are not even started.

Prompt
Using the table-driven Go test for Add with t.Run subtests, show the output of running only one case with go test -v -run "TestAdd/both_negative" — only that subtest should appear.
Output: Go test file and captured go test output