How to use testing package

Write Test functions with *testing.T arguments and run them using go test to automate verification of your Go code.

Use the testing package by writing functions that start with Test and accept a *testing.T argument, then run them with go test. The test runner executes these functions and reports failures if assertions fail or panics occur.

package main

import "testing"

func TestAdd(t *testing.T) {
	if 1+1 != 2 {
		t.Error("expected 2")
	}
}

Run the tests from the command line:

go test

For table-driven tests, define a slice of test cases and loop through them:

func TestAddTable(t *testing.T) {
	tests := []struct {
		a, b, want int
	}{
		{1, 2, 3},
		{0, 0, 0},
	}
	for _, tt := range tests {
		t.Run(fmt.Sprintf("%d+%d", tt.a, tt.b), func(t *testing.T) {
			if got := tt.a + tt.b; got != tt.want {
				t.Errorf("got %d, want %d", got, tt.want)
			}
		})
	}
}

Use t.Skip to skip tests conditionally and t.Fatalf to stop a test immediately on failure:

func TestConditional(t *testing.T) {
	if someCondition {
		t.Skip("skipping due to condition")
	}
	if badResult {
		t.Fatalf("critical failure: %v", badResult)
	}
}

For benchmarking, write functions starting with Benchmark that accept a *testing.B argument:

func BenchmarkAdd(b *testing.B) {
	for i := 0; i < b.N; i++ {
		_ = 1 + 1
	}
}

Run benchmarks with:

go test -bench=.

For fuzzing, write functions starting with Fuzz that accept a *testing.F argument:

func FuzzAdd(f *testing.F) {
	f.Add(1, 2)
	f.Fuzz(func(t *testing.T, a, b int) {
		_ = a + b
	})
}

Run fuzz tests with:

go test -fuzz=FuzzAdd

Use //go:debug directives in *_test.go files to control runtime behavior during tests:

//go:debug panicnil=1
package main

import "testing"

func TestPanicNil(t *testing.T) {
	defer func() {
		if r := recover(); r != nil {
			t.Logf("caught panic: %v", r)
		}
	}()
	panic(nil)
}

Verify default GODEBUG settings for your test package with:

go list -f '{{.DefaultGODEBUG}}' ./my/test/package