Open-Source Wikis

/

Go

/

How to contribute

/

Testing

golang/go

Testing

Go's tests are layered. The standard go test command works on every Go package, but the Go project itself has additional harnesses for the toolchain and runtime. This page covers all of them.

Layer 1: go test ./pkg

Every package under src/ has unit tests in _test.go files using the standard testing framework. From the repo's src/ directory:

go test ./fmt                          # test one package
go test ./...                          # test everything reachable from cwd
go test -short ./...                   # skip slow tests
go test -race ./net/http               # with the race detector
go test -count=10 -run TestFoo ./pkg   # repeat

Conventions worth knowing:

  • t.Skip("short") is wrapped by testing.Short() checks. The -short flag flips them. CI usually runs without -short.
  • testdata/ directories are off-limits to the build system (Go ignores any subdir named testdata). Each test package puts golden files there.
  • Network-dependent tests guard with testenv.SkipFlaky or testenv.MustHaveExternalNetwork. See internal/testenv for the helpers.

Layer 2: go test std cmd

To run every standard library and command package's tests at once:

go test std cmd
go test -short std cmd

std is a magic package list naming the standard library; cmd covers everything under src/cmd/. This is what cmd/dist test runs first.

Layer 3: cmd/dist test

cmd/dist is the build-system orchestrator (src/cmd/dist/). Its test subcommand runs the full Go test suite, with cmd/dist test -h listing dozens of named "buckets":

$ cmd/dist test -h
Usage: dist test [-h] [-v] [-list] [-keep-going] [-no-rebuild] [-banner string] [-run regexp] [-short] [bucket...]

Examples:

$ ./run.bash                         # run.bash invokes 'cmd/dist test'
$ cmd/dist test -short                # like all.bash but short
$ cmd/dist test runtime               # only the runtime bucket
$ cmd/dist test -list                 # list all buckets
$ cmd/dist test go_test:fmt           # only the fmt unit tests

The non-go test buckets cover:

  • The test/ directory (compiler/runtime regression programs).
  • API checks (api/).
  • Race-mode subsets.
  • cgo cross-compilation tests.
  • Vet against the standard library (go vet std cmd).
  • Asan/Msan modes.
  • Various OS- and arch-specific corners.

./all.bash is ./make.bash && ./run.bash. ./run.bash is cmd/dist test.

Layer 4: the test/ directory

test/ (top-level, sibling to src/) holds thousands of small Go programs that exercise compiler and runtime behaviors that cannot be expressed in _test.go form. Their harness is src/cmd/internal/testdir/.

Most files in test/ open with a comment like:

// errorcheck

// Test that calling f.G with no arguments fails.

These directives drive the test:

Directive Meaning
// run Compile and run the program; expect exit 0
// build Compile only; expect success
// compile Compile only; expect success (subtle difference from build)
// errorcheck Compile and check that errors match // ERROR "..." annotations on individual lines
// errorcheckdir Like errorcheck, but for a multi-file package
// rundir Run as a multi-file package
// runoutput Run, take stdout, run that as a Go program

Run individual tests:

go test cmd/internal/testdir                            # all of test/
go test cmd/internal/testdir -run='Test/escape.*\.go'   # filtered

This is where most compiler regressions live. When you fix a compiler bug, you usually add a small test/ program that triggers the bug.

Layer 5: trybots and longtests

Every CL must pass the trybots, a fleet of builders covering dozens of OS/arch combinations. They run a superset of cmd/dist test. The infrastructure lives in golang.org/x/build (separate repo).

Trybots also include "longtests" that run cmd/dist test without -short, plus specialty configurations:

  • linux-amd64-race, linux-amd64-asan, linux-amd64-msan
  • darwin-amd64-longtest, windows-amd64-longtest
  • ARM, ARM64, MIPS, RISC-V, PPC64 builders
  • A wasip1-wasm builder
  • A js-wasm builder

If a trybot fails on an arch you don't have, add Run-TryBot+1 after a fix and watch only that builder. The build dashboard at https://build.golang.org/ shows historical results.

Benchmarks

Standard go test -bench:

go test -bench=BenchmarkFoo ./pkg
go test -bench=. -count=10 -run='^$' ./pkg > new.txt

Compare results with benchstat:

go install golang.org/x/perf/cmd/benchstat@latest
benchstat old.txt new.txt

For the compiler itself, use compilebench:

go install golang.org/x/tools/cmd/compilebench@latest
compilebench -count=10 ./...

For runtime/GC behavior, the canonical microbenchmarks live in src/runtime/*_test.go (e.g., BenchmarkChanProdCons, BenchmarkAllocation*).

Fuzzing

Native fuzz tests live in src/. They look like:

func FuzzParse(f *testing.F) {
    f.Add("seed input")
    f.Fuzz(func(t *testing.T, s string) {
        Parse(s)
    })
}

Run them:

go test -fuzz=FuzzParse -fuzztime=30s ./pkg

The fuzzing engine lives under src/internal/fuzz/. Crash-reproducing inputs are written to testdata/fuzz/<FuzzFunc>/.

Race detector

go test -race ./...

The race detector wraps tests with TSan. The supporting Go-side files are src/runtime/race*.go; the C runtime library is vendored under src/runtime/race/.

Many runtime-internal tests are race-sensitive. The race.bash helper runs the race-tagged subset.

Asan and Msan

go test -asan ./...                # AddressSanitizer
go test -msan ./...                # MemorySanitizer (requires clang)

These require cgo and a recent clang. Stub Go files: runtime/asan*.go, runtime/msan*.go.

Coverage

For any package:

go test -cover ./pkg
go test -coverprofile=cover.out ./pkg
go tool cover -html=cover.out

Whole-binary coverage (Go 1.20+):

go install -cover -coverpkg=./... ./cmd/foo
mkdir /tmp/coverdir
GOCOVERDIR=/tmp/coverdir ./foo
go tool covdata textfmt -i=/tmp/coverdir -o cover.out

The implementation lives in src/cmd/internal/cov/ and src/runtime/coverage/.

What to run before mailing a CL

For most CLs, this is enough:

go install ./...                   # rebuild relevant tools
go test -short -race ./affected/... # local, fast

For compiler or runtime CLs, add:

cd src
./run.bash                         # full local test suite (slow)

For everything else, rely on the trybots after Run-TryBot+1.

Built by Factory AutoWiki from public repository content. It is a generated preview for codebase exploration, not source-maintained documentation.

Testing – Go wiki | Factory