Run a Single Go Test or Subtest From the Command Line
Run one Go test or subtest with go test -run: how the regular expression matches each slash level, anchors, names with spaces, -list and -skip.

When one test fails you want to run that test alone, quickly, with its output visible. go test -run does that, and it is worth knowing exactly how the pattern is interpreted, because the first thing most people try runs more than they expected.
Tested with Go 1.25.6, macOS on Apple Silicon (arm64)
The lab has three tests: TestParse with subtests empty, short and long, TestParseHeader with none, and TestRender with subtests empty and full page.
package main
import "testing"
func TestParse(t *testing.T) {
for _, n := range []string{"empty", "short", "long"} {
t.Run(n, func(t *testing.T) {})
}
}
func TestParseHeader(t *testing.T) {}
func TestRender(t *testing.T) {
t.Run("empty", func(t *testing.T) {})
t.Run("full page", func(t *testing.T) {})
}package main
func main() {}show() { echo "\$ go test $*"; go test -count=1 -v "$@" . 2>&1 | grep -E '^(=== RUN|ok|FAIL|no tests)|^TestPick|^Test' | sed -E 's/^=== RUN +//; s/[[:space:]]+[0-9.]+s$//'; }
show -run 'TestParse'
show -run '^TestParse$'
show -run 'TestParse/short'
show -run '/empty'
show -run 'TestRender/full_page'
show -run 'Parse$/^l'
echo '$ go test -list .'
go test -list . . | grep -v '^ok'
echo '$ go test -skip TestParseHeader -v'
go test -count=1 -skip 'TestParseHeader' -v . 2>&1 | grep -E '^=== RUN' | sed -E 's/^=== RUN +//'$ go test -run TestParse
TestParse
TestParse/empty
TestParse/short
TestParse/long
TestParseHeader
ok example.test/lab
$ go test -run ^TestParse$
TestParse
TestParse/empty
TestParse/short
TestParse/long
ok example.test/lab
$ go test -run TestParse/short
TestParse
TestParse/short
TestParseHeader
ok example.test/lab
$ go test -run /empty
TestParse
TestParse/empty
TestParseHeader
TestRender
TestRender/empty
ok example.test/lab
$ go test -run TestRender/full_page
TestRender
TestRender/full_page
ok example.test/lab
$ go test -run Parse$/^l
TestParse
TestParse/long
ok example.test/lab
$ go test -list .
TestParse
TestParseHeader
TestRender
$ go test -skip TestParseHeader -v
TestParse
TestParse/empty
TestParse/short
TestParse/long
TestRender
TestRender/empty
TestRender/full_pageThe pattern is a regular expression
-run takes a regular expression and runs the tests whose names match it. It is not anchored, so -run TestParse matches TestParse and TestParseHeader, as the first block shows. To select exactly one top-level test, anchor it: -run '^TestParse$' ran TestParse and its three subtests and nothing else. Quote the pattern; $ and ^ mean something to the shell.
One pattern per slash level
For subtests, the pattern is split on slashes, and each part is matched against the corresponding level of the name. -run 'TestParse/short' means: top-level name matches TestParse, subtest name matches short. In the output only the short subtest of TestParse ran, not empty or long.
You can leave a level empty to match anything: -run '/empty' ran the empty subtest of both TestParse and TestRender. That is handy for a name you reuse across tests.
Each level has its own regular expression, so anchors work per level: -run 'Parse$/^l' selected TestParse (and not TestParseHeader, because of the $) and, inside it, the subtest starting with l, which is long.
Spaces in subtest names
The subtest named full page is selected as full_page: Go rewrites spaces in subtest names to underscores, and the pattern must use the rewritten name. -run 'TestRender/full_page' ran it. Other unprintable characters are escaped too, and -v output shows the names you should type.
The gotcha with tests that have no subtests
Look at the third and fourth blocks. -run 'TestParse/short' printed TestParseHeader as well. TestParseHeader has no subtests, and its top-level name matches the first part of the pattern, so it runs; there is nothing at the second level to filter. The same happened with -run '/empty'. A function whose top-level name matches runs completely; the later parts of the pattern only filter subtests that exist. Anchor the first part (^TestParse$/short) if you want only one test.
Listing and skipping
go test -list . prints the names of the top-level tests, benchmarks, fuzz tests and examples that match a pattern, without running anything. It lists top-level names only, since subtests exist only at run time. Use it to check a pattern, or in a script that runs tests one by one.
-skip (Go 1.20) is the inverse of -run: tests matching the pattern are not run. -skip 'TestParseHeader' ran everything else, subtests included. It accepts the same slash syntax. The two combine: -run Parse -skip Header.
Habits
- Add
-count=1when you rerun a test you did not change, to avoid a cached "ok" (the basics). - Add
-vto see the test names and logs, and-raceif goroutines are involved. - When a table test fails, the failure output names the subtest, so copy it into
-run(with underscores) to iterate on that row (table-driven tests). - In an editor, use the "run test" action; it passes an anchored
-runfor you. - For a package other than the current one, add the path:
go test -run '^TestX$' ./internal/store.
The pattern syntax is documented in the testing flags reference and the matching rules under T.Run. For parallel subtests and ordering, see subtests and parallel tests.


