Lab 10: Testing

Time: 30 minutes | Level: Practitioner | Docker: docker run -it --rm golang:1.22-alpine sh

Overview

Go has first-class testing support built in. The testing package, go test command, and httptest package make it easy to write unit tests, benchmarks, and integration tests without third-party libraries.

Step 1: Basic Tests with testing.T

// calc/calc.go
package calc

func Add(a, b int) int      { return a + b }
func Subtract(a, b int) int { return a - b }
func Multiply(a, b int) int { return a * b }
// calc/calc_test.go
package calc

import "testing"

func TestAdd(t *testing.T) {
    got := Add(2, 3)
    want := 5
    if got != want {
        t.Errorf("Add(2, 3) = %d; want %d", got, want)
    }
}

func TestSubtract(t *testing.T) {
    if got := Subtract(10, 3); got != 7 {
        t.Errorf("Subtract(10, 3) = %d; want 7", got)
    }
}

💡 Tip: Test files must end in _test.go. Test functions must start with Test and take *testing.T.

Step 2: Table-Driven Tests

The idiomatic Go testing pattern — test many cases with one function.

Step 3: Subtests with t.Run

t.Run creates named subtests that can be run individually.

💡 Tip: Spaces in subtest names become underscores in go test -run patterns.

Step 4: Benchmarks

Step 5: Test Helpers

Step 6: httptest.NewRecorder — HTTP Handler Tests

Step 7: Coverage

Output example:

Step 8: Capstone — Full Test Suite

Run:

📸 Verified Output:

Summary

Command
Purpose

go test ./...

Run all tests

go test -v ./...

Verbose output

go test -run TestName

Run matching tests

go test -bench=. ./...

Run benchmarks

go test -benchmem

Show allocs in benchmarks

go test -cover

Show coverage %

go test -coverprofile=out.cov

Generate coverage profile

go test -race ./...

Detect data races

t.Run(name, func)

Subtests

t.Helper()

Mark as test helper (better error lines)

t.Fatal / t.Error

Fatal stops; Error continues

httptest.NewRecorder()

Capture HTTP handler output

httptest.NewServer(h)

Real TCP server for client tests

Last updated