×

go · level 3 · unit 7 · lesson 1

  1. meet it
  2. guess first
  3. your turn
  4. fix it
  5. nailed it

Tap a green word if you get lost.

meet it

A lists its cases as data, then loops.

A table-driven test lists its cases as data: a slice of small structs, each with a name, an input and the answer you want. The struct type is written in place, with no name of its own: an . One loop runs every case and compares what came out with what you wanted.

Adding a case is one more line, not one more function. Make failures quick to read: say which case failed, what went in, what came out and what was wanted, in the order got, then want.

In a real project the table lives in a file ending _test.go, inside func TestSlug(t *testing.T), where each case runs with t.Run and reports with t.Errorf. Here the same loop runs from main.

package main
import (
	"fmt"
	"strings"
)
func slug(title string) string {
	return strings.ToLower(strings.Join(strings.Fields(title), "-"))
}
func main() {
	tests := []struct {
		name, in, want string
	}{
		{"spaces", "Hello World", "hello-world"},
		{"extra spaces", "  Go   Level 3 ", "go-level-3"},
		{"empty", "", ""},
	}
	for _, tt := range tests {
		if got := slug(tt.in); got != tt.want {
			fmt.Printf("FAIL %s: slug(%q) = %q, want %q\n", tt.name, tt.in, got, tt.want)
		} else {
			fmt.Println("PASS", tt.name)
		}
	}
}

tt is the usual Go name for the current row of a test table.