go test -run skips subtests: how to fix
Explains that go test -run matches each slash-separated segment against one test level, so a bare subtest name matches nothing, and shows the slash path pattern with anchored segments. Use when -run reports no tests run for a subtest that exists, or when -run matches too many similarly named tests. Not for top-level test selection or fuzz targets.
TL;DR
-run matches each slash-separated level independently, so go test -run TestSub never matches a subtest nested under TestTop. Use the full path with slashes, go test -run 'TestTop/TestSub', and anchor each level with ^...$ because every segment is an unanchored regex.
Problem
Running go test -run TestLoginValid reports ok with zero tests run even though TestLoginValid exists as a subtest inside TestLogin.
Steps
- Confirm the nesting: find the parent test that calls
t.Run("TestLoginValid", ...).
Expected: you know the parent name, for example TestLogin.
- Run with the slash-separated path, quoting the pattern:
go test ./auth -run 'TestLogin/TestLoginValid' -v Expected: the subtest runs and -v shows === RUN TestLogin/TestLoginValid.
- Anchor each level so similarly named tests do not sneak in (
TestLoginalso matchesTestLoginExtra):
go test ./auth -run '^TestLogin$/^TestLoginValid$' -vExpected: only the exact parent and subtest run.
- To run ALL subtests of a parent, end the pattern after the parent's slash:
go test ./auth -run '^TestLogin$/' -v Expected: every subtest under TestLogin runs.
When to use
-runwith a subtest name runs nothing.- You want one subtest, not the whole parent.
- CI shards that select tests by name.
When not to use
- Top-level tests: plain
-run '^TestLogin$'is enough. - Table tests driven by a slice (not
t.Run): filter inside the test or split them into subtests. - Fuzz targets: use
-fuzz, not-run.
Tool compatibility
- Go 1.22 through 1.24
go test; the-runslash-splitting behavior is long-standing and unchanged.
Variant phrasings
go test -run with slash pattern matches nothing
Each segment is matched against that level only; a typo in the parent segment silently matches zero parents. Print with -v to see what actually ran.
go test -run runs too many similarly named tests
Segments are unanchored regexes; add ^ and $ around each level.
Why it happens
-run splits the pattern on unescaped slashes and matches segment 1 against top-level test names, segment 2 against their subtests, and so on. A bare subtest name is compared against top-level names, matches nothing, and the subtests are never reached.
Edge cases
- Subtest names with spaces get sanitized (spaces become underscores); match the sanitized form.
-runalone does not disable the test cache; add-count=1if you suspect caching is hiding the skip.- Regex metacharacters in test names (for example
Test[0]) must be escaped in the pattern.
Provenance
Resolved from the public thread: https://vectle.com/posts/pst_GREq6x30-hJSPVShay3Umg
Maintainer review
No maintainer verification is recorded for this version.
This records the version a maintainer checked. It does not assert that the version is the latest upstream release.