Running Tests with go test
Run all tests in a Go project, run one test or one file, show verbose output, disable caching with -count=1, add timeouts, and run tests in parallel.
go test has many flags, but a handful cover almost everything you will need day to day: running every test, running one test, seeing output, and making sure results are not cached.
Running Everything
go test ./...
./... means "this folder and every folder below it". Each package is compiled and tested separately:
ok example.com/shop/internal/order 0.012s
ok example.com/shop/internal/price (cached)
? example.com/shop/cmd/shop [no test files]
(cached) means nothing changed since the last passing run, so Go reused the result. [no test files] means the package has no tests.
Running One Test
-run takes a regular expression matched against test names:
go test -run TestSlug ./textutil
go test -run '^TestSlug$' ./textutil # exactly TestSlug, not TestSlugify
go test -run 'TestOrder/empty_cart' ./... # one subtest
There is no flag to run "the tests in one file", because Go works with packages, not files. Give your tests names that -run can match instead. Passing file names, as in go test slug_test.go, only compiles those files, which usually fails with undefined: errors for code in the other files.
Verbose Output
By default, passing tests print nothing. -v shows each test as it runs, plus anything logged with t.Log:
go test -v -run TestSlug ./textutil
=== RUN TestSlug
--- PASS: TestSlug (0.00s)
PASS
ok example.com/site/textutil 0.002s
t.Log only shows on failure or with -v:
Messages from t.Log and t.Logf are hidden for passing tests unless you pass -v. That keeps output quiet while still letting tests leave helpful context for when they fail.
Turning Off the Cache
go test -count=1 ./...
-count=1 forces every test to run again. Use it when tests depend on things outside the code, such as files, environment variables or a database, which Go cannot see changing.
Timeouts, Short Mode and Failing Fast
go test -timeout 30s ./... # default is 10 minutes
go test -short ./... # tests can skip slow parts
go test -failfast ./... # stop after the first failing test
When a test runs past the timeout, Go prints panic: test timed out after 30s with the stack of every goroutine, which is a quick way to find a test stuck on a channel or lock.
Inside a test, testing.Short() reports whether -short was given:
// file: slow_test.go
package slow
import "testing"
func TestBigImport(t *testing.T) {
if testing.Short() {
t.Skip("skipping slow import test in -short mode")
}
// slow work here
}
Running Tests in Parallel
t.Parallel() lets a test run at the same time as other parallel tests in the same package:
// file: parallel_test.go
package parallel
import (
"testing"
"time"
)
func TestA(t *testing.T) {
t.Parallel()
time.Sleep(50 * time.Millisecond)
}
func TestB(t *testing.T) {
t.Parallel()
time.Sleep(50 * time.Millisecond)
}
Both tests finish in about 50ms in total instead of 100ms. Only mark tests parallel when they do not share state such as global variables or the same temp files.
Packages already run in parallel:
go test ./... runs different packages at the same time by default. Two packages that use the same database or port can interfere with each other even without t.Parallel(). Use separate resources or -p 1 to run packages one by one.
Always run -race on concurrent code:
go test -race ./... adds the race detector. Make it part of CI for any package that uses goroutines.
A good everyday command:
go test -race -count=1 ./... runs everything fresh with race detection. If it passes locally and in CI, your tests are in good shape.
Summary
go test ./... runs every package, -run selects tests by name with a regular expression, and -v shows each test and its logs. -count=1 bypasses the cache, -timeout, -short and -failfast control slow or failing runs, and t.Parallel() speeds up independent tests. Add -race for anything concurrent.