Running One Table-Driven Case in GoLand Without Editing the Test
GoLand surfaces individual table-driven test cases in the Test Explorer and offers module-aware refactorings. Here is when IDE-driven test workflows help and where they cost in medium to large Go codebases.
06 Oct 2026, 04:53 UTC

In Go codebases, table-driven tests compress many scenarios into one test function. The practical pain appears when a single case fails: you end up editing the file, commenting out rows, or re-running the whole suite to isolate it. GoLand reduces that friction by surfacing individual cases from a table-driven test and by offering module-aware refactorings that keep go.mod and go.work consistent.
The problem with running a single case
Table-driven tests use a slice of structs and a for loop, often with t.Run to create subtests. The test runner sees one function, but developers think in cases. Without IDE support, running one case means manual edits or command-line filters that are easy to leave behind.
The useful takeaway is that GoLand detects the pattern via naming conventions and struct literals and presents each case as a first-class node in the Test Explorer. You can run, debug, or skip a case without touching the source.
How GoLand surfaces table-driven tests
Detection relies on recognizable shapes: a variable named tests or similar, a slice of struct literals, and a for _, tt := range tests loop that calls t.Run with tt.name. When the pattern is recognized, the Test Explorer expands the test function into per-case children.
Navigation and execution happen from the editor gutter and the Test tool window. Per-case run and debug use the built-in Delve integration, which attaches to the test process and shows variables, watches, and conditional breakpoints in the editor. Coverage highlighting can be viewed per case after running a test with coverage enabled.
Verification steps you can perform locally:
- Create a Go module with a table-driven test using tests := []struct{name string; in string; want error}{...} and for _, tt := range tests { t.Run(tt.name, func(t *testing.T){...}) }
- Open Settings > Go > Tests to confirm table-driven test detection is enabled for the project.
- Open the Test Explorer and check whether the test function expands into individual case nodes.
UI names and grouping behavior are version-sensitive. Table-driven test grouping and workspace handling evolved across GoLand 2022-2025 releases, so the exact labels may differ.
Module-aware refactoring that keeps go.mod honest
GoLand provides Go-specific refactorings such as Extract Interface, Change Signature, and Inline Variable. They are module-aware and attempt to preserve go.mod and go.work dependencies, which reduces manual edits in monorepos.
A worked example shape:
func TestParse(t *testing.T) {
tests := []struct {
name string
in string
want error
}{
{name: "empty", in: "", want: nil},
{name: "bad", in: "!", want: fmt.Errorf("invalid")},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := Parse(tt.in)
if !errors.Is(err, tt.want) {
t.Fatalf("got %v want %v", err, tt.want)
}
})
}
}If you place the cursor on Parse and invoke Refactor > Extract Interface, the IDE proposes an interface based on usage and updates import paths across modules. Inspect go.mod and the affected files to verify that changes are confined to intended modules. Refactorings assume a standard go.mod layout and may conflict with custom code generators or external lint pipelines if those tools expect specific formatting.
Trade-offs in medium to large codebases
Heavy indexing and continuous test discovery increase memory and startup time on large monorepos with many modules. The IDE keeps a model of tests, symbols, and dependencies to enable per-case runs and safe refactorings, which costs resources.
Debugging relies on a local Delve instance and Go toolchain configuration. Remote or containerized targets require additional run configuration setup. Toolchain selection per module is supported via Go workspaces, but you must configure the SDK per module to avoid mismatched versions.
Code generation and inspections for struct tags, error wrapping, and Go 1.18+ generics keep code idiomatic, yet quick fixes can change signatures broadly. Review changes in a diff before committing.
Check it works in your project
Enable detection in Settings > Go > Tests, open a representative table-driven test file, and confirm the Test Explorer lists individual cases. Run a single case with coverage and observe per-case highlighting. Try a small refactoring such as Inline Variable on a test helper and verify imports and go.mod remain consistent. Monitor IDE memory and indexing time after opening a large workspace, and disable continuous test discovery if startup becomes a bottleneck.
0 replies
A thoughtful contribution can make all the difference. Be the first to share one.