Drills

Drills — write the tests

Reading tests isn't enough — you have to write them. Five drills: for each, write a table-driven test for a function you already have (from earlier lessons), run go test, and compare with the solution. The function is named in each; the solution is the test.

1 (easy) — test sumRange (lesson 5): sums the integers from a to b.

func TestSumRange(t *testing.T) {
    cases := []struct {
        a, b, want int
    }{
        {1, 5, 15},
        {3, 3, 3},
        {0, 0, 0},
    }
    for _, c := range cases {
        if got := sumRange(c.a, c.b); got != c.want {
            t.Errorf("sumRange(%d, %d) = %d, want %d", c.a, c.b, got, c.want)
        }
    }
}

2 (easy) — test digitSum (lesson 5): sums the digits. Include a negative to check that edge.

func TestDigitSum(t *testing.T) {
    cases := []struct {
        in, want int
    }{
        {1234, 10},
        {0, 0},
        {-52, 7},
    }
    for _, c := range cases {
        if got := digitSum(c.in); got != c.want {
            t.Errorf("digitSum(%d) = %d, want %d", c.in, got, c.want)
        }
    }
}

3 (medium) — test slug (lesson 7): lowercase, spaces → hyphens, trimmed.

func TestSlug(t *testing.T) {
    cases := []struct {
        in, want string
    }{
        {"  The Go Language ", "the-go-language"},
        {"Go", "go"},
    }
    for _, c := range cases {
        if got := slug(c.in); got != c.want {
            t.Errorf("slug(%q) = %q, want %q", c.in, got, c.want)
        }
    }
}

4 (medium) — test grade (lesson 5). The bugs live at the boundaries — test 90, 89, 80, not just "a good score".

func TestGrade(t *testing.T) {
    cases := []struct {
        score int
        want  string
    }{
        {90, "A"},
        {89, "B"},
        {80, "B"},
        {69, "F"},
    }
    for _, c := range cases {
        if got := grade(c.score); got != c.want {
            t.Errorf("grade(%d) = %q, want %q", c.score, got, c.want)
        }
    }
}

5 (harder) — test the too-long branch of validateTitle. You must build an input of an exact length. Use strings.Repeat — and remember it's characters that count, so 41 "ą" is over the 40-character limit (even though it's 82 bytes).

func TestValidateTitleTooLong(t *testing.T) {
    long := strings.Repeat("ą", 41) // 41 characters, 82 bytes
    got := validateTitle(long)
    want := "title is too long (max 40 characters)"
    if got != want {
        t.Errorf("validateTitle(41 chars) = %q, want %q", got, want)
    }
}

Tip. Want to see red? Change one want to a wrong value on purpose and run go test — read the failure line, then change it back. Knowing what a failing test looks like is half of trusting a passing one.