Module 2 · Exercise 2 · ~30 min · Real Go code

Build a Table-Driven Test Suite

Implement an Offset parser AND write its full test suite from scratch — table-driven, with subtests and sentinel-error checks. The same shape you'll use to test every Canton-adjacent type you write.

Where
cd module-02-idiomatic-go/exercises/exercise-02-table-tests
go test -v ./...

What's there

Loop

  1. Run go test -v ./.... You'll see the smoke test pass and nothing else.
  2. Implement TODOs in offset.go.
  3. Write TestParseOffset table-driven, covering all 12 listed cases.
  4. Run again. Iterate until all cases pass.
  5. Delete the smoke test.

Pattern reminder

func TestParseOffset(t *testing.T) {
    cases := []struct {
        name    string
        input   string
        want    Offset
        wantErr error     // nil for happy path; sentinel for error cases
    }{
        {"empty", "", 0, ErrEmpty},
        // ... 11 more cases
    }
    for _, c := range cases {
        t.Run(c.name, func(t *testing.T) {
            got, err := ParseOffset(c.input)
            if c.wantErr != nil {
                if !errors.Is(err, c.wantErr) {
                    t.Errorf("err: want %v, got %v", c.wantErr, err)
                }
                return
            }
            if err != nil { t.Fatalf("unexpected: %v", err) }
            if got != c.want { t.Errorf("got %d, want %d", got, c.want) }
        })
    }
}

Why bother

Table-driven tests scale to dozens of cases without code duplication, give you per-case pass/fail in CI output, and let you isolate a single case from the command line. Once you've internalized the pattern, you'll reach for it constantly. It's the single most important Go testing idiom.