Documentation Index Fetch the complete documentation index at: https://mintlify.com/golang/go/llms.txt
Use this file to discover all available pages before exploring further.
The go test command automates testing the packages named by import paths. It compiles test files, runs test functions, and reports results.
Overview
Testing is a first-class citizen in Go. The go test command provides built-in support for unit tests, benchmarks, examples, and fuzz tests.
Basic Usage
go test [build/test flags] [packages] [build/test flags & test binary flags]
Current Package
Multiple Packages
# Test current package
go test
# Test with verbose output
go test -v
# Test current package (explicit)
go test .
Test Files
Test File Naming
Test files must:
End with _test.go
Be in the same package directory
Not start with _ or .
Internal Tests (same package)
External Tests (separate package)
// mypackage_test.go
package mypackage
import " testing "
func TestInternal ( t * testing . T ) {
// Can access unexported functions
result := internalFunc ()
if result != expected {
t . Errorf ( "got %v , want %v " , result , expected )
}
}
Test Modes
Local Directory Mode
Invoked without package arguments:
Compiles package in current directory
Runs test binary immediately
Caching is disabled
Prints summary after completion
Package List Mode
Invoked with explicit package arguments:
go test ./...
go test example.com/myapp
Compiles and tests each listed package
Results are cached
Prints ‘ok’ for passing tests
Shows full output for failures
Common Test Flags
Test Selection
Run only tests matching regexp # Run specific test
go test -run TestMyFunction
# Run tests matching pattern
go test -run "Test.*Integration"
# Run subtests
go test -run TestMyFunc/subtest_name
Skip tests matching regexp go test -skip "TestSlow|TestExternal"
Output Control
Verbose output - print all test names and results
Output test results as JSON go test -json
go test -json | tee test-results.json
Test Execution
Run each test n times (default: 1) # Disable test caching
go test -count=1
# Run tests multiple times
go test -count=10
Maximum number of tests to run in parallel (default: GOMAXPROCS)
Timeout for entire test execution (default: 10m) go test -timeout 30s
go test -timeout 5m
Run in short mode - skip long-running tests In test code: if testing . Short () {
t . Skip ( "skipping test in short mode" )
}
Stop after first test failure
Coverage Flags
Write coverage profile to file go test -coverprofile=coverage.out
Set coverage mode
set: boolean (was this line executed?)
count: count how many times each line executed
atomic: like count, but correct for concurrent tests
go test -covermode=count -coverprofile=coverage.out
Writing Tests
Basic Test Function
Create Test File
Create a file ending in _test.go: // math_test.go
package math
import " testing "
Write Test Function
Test functions must start with Test and take *testing.T: func TestAdd ( t * testing . T ) {
result := Add ( 2 , 3 )
expected := 5
if result != expected {
t . Errorf ( "Add(2, 3) = %d ; want %d " , result , expected )
}
}
Table-Driven Tests
func TestAdd ( t * testing . T ) {
tests := [] struct {
name string
a , b int
expected int
}{
{ "positive numbers" , 2 , 3 , 5 },
{ "negative numbers" , - 2 , - 3 , - 5 },
{ "mixed signs" , - 2 , 3 , 1 },
{ "zeros" , 0 , 0 , 0 },
}
for _ , tt := range tests {
t . Run ( tt . name , func ( t * testing . T ) {
result := Add ( tt . a , tt . b )
if result != tt . expected {
t . Errorf ( "Add( %d , %d ) = %d ; want %d " ,
tt . a , tt . b , result , tt . expected )
}
})
}
}
Run specific subtests:
# Run all Add tests
go test -run TestAdd
# Run specific subtest
go test -run TestAdd/positive
Testing Methods
Report error but continue test: t . Error ( "something went wrong" )
t . Errorf ( "got %v , want %v " , result , expected )
Report error and stop test immediately: t . Fatal ( "critical failure" )
t . Fatalf ( "setup failed: %v " , err )
Print log output (only shown with -v or on failure): t . Log ( "debug information" )
t . Logf ( "processing item %d " , i )
Skip test: if runtime . GOOS == "windows" {
t . Skip ( "skipping on Windows" )
}
Register cleanup function: tmpFile , err := os . CreateTemp ( "" , "test" )
if err != nil {
t . Fatal ( err )
}
t . Cleanup ( func () {
os . Remove ( tmpFile . Name ())
})
Benchmarks
Writing Benchmarks
func BenchmarkAdd ( b * testing . B ) {
for i := 0 ; i < b . N ; i ++ {
Add ( 2 , 3 )
}
}
func BenchmarkComplexOperation ( b * testing . B ) {
// Setup (not timed)
data := setupData ()
b . ResetTimer () // Reset timer after setup
for i := 0 ; i < b . N ; i ++ {
ComplexOperation ( data )
}
}
Running Benchmarks
Basic Benchmarks
Benchmark Options
Save Results
# Run all benchmarks
go test -bench=.
# Run specific benchmark
go test -bench=BenchmarkAdd
# Run benchmarks matching pattern
go test -bench= "Complex.*"
Examples
Writing Examples
func ExampleAdd () {
result := Add ( 2 , 3 )
fmt . Println ( result )
// Output: 5
}
func ExampleAdd_negative () {
result := Add ( - 2 , - 3 )
fmt . Println ( result )
// Output: -5
}
func ExamplePerson_String () {
p := Person { Name : "Alice" , Age : 30 }
fmt . Println ( p )
// Output: Alice (30 years old)
}
Examples serve as both documentation and tests.
Code Coverage
Generate Coverage Profile
go test -coverprofile=coverage.out
View Coverage Report
# Text summary
go tool cover -func=coverage.out
# HTML visualization
go tool cover -html=coverage.out
Coverage for Multiple Packages
go test -coverprofile=coverage.out ./...
go tool cover -html=coverage.out
Coverage Options
# Specify packages to cover
go test -coverpkg=./... -coverprofile=coverage.out
# Different coverage modes
go test -covermode=set -coverprofile=coverage.out
go test -covermode=count -coverprofile=coverage.out
go test -covermode=atomic -coverprofile=coverage.out
Test Caching
Go caches successful test results to avoid unnecessary reruns.
Cacheable Flags
Tests are cached when using only these flags:
-benchtime
-cpu
-coverprofile
-failfast
-fullpath
-list
-outputdir
-parallel
-run
-short
-skip
-timeout
-v
Disabling Cache
Using -count=1
Clear Cache
# Idiomatic way to disable cache
go test -count=1
Advanced Testing
Setup and Teardown
func TestMain ( m * testing . M ) {
// Setup before all tests
setup ()
// Run tests
code := m . Run ()
// Teardown after all tests
teardown ()
os . Exit ( code )
}
Parallel Tests
func TestParallel ( t * testing . T ) {
t . Parallel () // Mark test as parallelizable
// Test code here
}
func TestParallelSubtests ( t * testing . T ) {
tests := [] struct {
name string
// ...
}{
// test cases
}
for _ , tt := range tests {
tt := tt // Capture range variable
t . Run ( tt . name , func ( t * testing . T ) {
t . Parallel ()
// Subtest code
})
}
}
Using testdata Directory
mypackage/
├── myfile.go
├── myfile_test.go
└── testdata/
├── input.json
└── expected.txt
func TestWithTestdata ( t * testing . T ) {
data , err := os . ReadFile ( "testdata/input.json" )
if err != nil {
t . Fatal ( err )
}
// Use data in test
}
Test Compilation
Compile Test Binary
# Compile but don't run
go test -c
# Compile with custom output name
go test -c -o mytest.test
# Run compiled test binary
./mytest.test
./mytest.test -test.v -test.run TestSpecific
Binary Flags
Compiled test binaries accept -test.* flags:
./mytest.test -test.v
./mytest.test -test.run TestMyFunc
./mytest.test -test.bench=.
./mytest.test -test.cpuprofile=cpu.prof
CI/CD Integration
GitHub Actions
.github/workflows/test.yml
name : Test
on : [ push , pull_request ]
jobs :
test :
runs-on : ubuntu-latest
steps :
- uses : actions/checkout@v4
- uses : actions/setup-go@v5
with :
go-version : '1.21'
- name : Run tests
run : go test -v -race -coverprofile=coverage.out ./...
- name : Upload coverage
uses : codecov/codecov-action@v3
with :
files : ./coverage.out
Makefile
.PHONY : test
test :
go test -v -race -coverprofile=coverage.out ./...
.PHONY : test-short
test-short :
go test -short ./...
.PHONY : coverage
coverage : test
go tool cover -html=coverage.out
.PHONY : bench
bench :
go test -bench=. -benchmem ./...
Troubleshooting
Tests are cached when they shouldn't be
# Disable caching
go test -count=1
# Or clear cache
go clean -testcache
# Increase timeout
go test -timeout 30m
# Check for infinite loops or deadlocks
go test -timeout 10s -v
# Run with race detector
go test -race
# May need more memory
GORACE = "history_size=7" go test -race
See Also
go Command Overview of go command
Building Building Go programs
Benchmarking Performance testing