CheckOps home

Tools directory

G

CheckOps

Go testing package

Go's built-in testing package and go test command provide unit tests, table-driven subtests, benchmarks, fuzzing, examples and coverage with no third-party dependencies.

Visit website

Latest public signals

Not refreshed yet. Refresh reads the public site and, when the entry has a GitHub repository, the latest release.

Visit Website

Introduction

Go ships testing support in its standard library. The testing package, used with the go test command, runs any function of the form func TestXxx(t *testing.T) in files ending in _test.go. Because it is part of the toolchain, every Go project has the same test conventions, and no framework choice is required to get started.

The package covers far more than basic tests. t.Run creates subtests, which makes table-driven tests the idiomatic Go style; t.Parallel() runs tests concurrently; t.Cleanup, t.TempDir and t.Setenv simplify fixtures; benchmarks (func BenchmarkXxx(b *testing.B)) measure performance; native fuzzing (func FuzzXxx(f *testing.F), added in Go 1.18) generates inputs and stores failing cases in testdata/fuzz; and ExampleXxx functions double as runnable documentation. go test -cover and -coverprofile produce coverage, -race enables the race detector, and -run/-bench select tests by pattern. Go is BSD-3-Clause licensed.

Test helpers call t.Helper() so failures point at the calling line, and testing/fstest, net/http/httptest and testing/iotest in the standard library provide ready-made fakes for file systems, HTTP servers and readers.

Features

  1. Built into Go: No dependencies; go test everywhere.
  2. Subtests and parallelism: Table-driven tests with t.Run and t.Parallel.
  3. Benchmarks and fuzzing: Performance and native fuzz testing.
  4. Coverage and race detection: -cover, -coverprofile and -race.

Pros

  1. Free: Included with Go.
  2. Consistent: The same conventions in every Go project.

Cons

  1. Minimal assertions: Checks are plain if statements; many teams add testify or go-cmp.
  2. No built-in mocking: Use interfaces with hand-written fakes or gomock.
// price_test.go
package price

import "testing"

func TestApply(t *testing.T) {
    tests := []struct {
        name           string
        price, pct, want int
    }{
        {"no discount", 100, 0, 100},
        {"ten percent", 100, 10, 90},
    }
    for _, tc := range tests {
        t.Run(tc.name, func(t *testing.T) {
            if got := Apply(tc.price, tc.pct); got != tc.want {
                t.Errorf("Apply(%d, %d) = %d, want %d", tc.price, tc.pct, got, tc.want)
            }
        })
    }
}

func FuzzApply(f *testing.F) {
    f.Add(100, 10)
    f.Fuzz(func(t *testing.T, price, pct int) { _ = Apply(price, pct) })
}
go test ./... -race -cover
go test -fuzz=FuzzApply -fuzztime=30s

Resources:

Pricing

Free as part of the Go toolchain (BSD-3-Clause licence).

  1. Every Go project, as the foundation of its test suite.
  2. Teams wanting benchmarks and fuzzing without extra tools.

Conclusion

Go’s testing package is a complete, standard foundation for unit tests, benchmarks and fuzzing, often extended with small helper libraries.

Alternatives

Other tools on CheckOps that cover similar ground. Open a page, or compare one with Go testing package side by side.