Skip to content

Commit 7322ae4

Browse files
authored
doc: add guidance on parallel tests (#3476)
1 parent 99bff58 commit 7322ae4

1 file changed

Lines changed: 37 additions & 0 deletions

File tree

doc/howwewritego.md

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -280,6 +280,43 @@ func TestSendMessage_Error(t *testing.T) {
280280
}
281281
```
282282

283+
### Running tests in parallel
284+
285+
Large table-driven tests and/or those that are I/O bound e.g. by making
286+
filesystem reads or network requests are good candidates for parallelization via
287+
[`t.Parallel()`](https://pkg.go.dev/testing#T.Parallel). Do not
288+
parallelize lightweight, millisecond-level tests.
289+
290+
**Important:** A test cannot be parallelized if it depends on shared resources,
291+
mutates the process as a whole e.g. by invoking `t.Chdir()`, or is dependent on
292+
execution order.
293+
294+
When using `t.Parallel()` in table-driven tests, you must capture the range
295+
variable to avoid race conditions. This ensures each subtest gets the correct
296+
data from its corresponding test case.
297+
298+
```go
299+
func TestTransform(t *testing.T) {
300+
for _, test := range []struct {
301+
name string
302+
input string
303+
want string
304+
}{
305+
{"uppercase", "hello", "HELLO"},
306+
{"empty", "", ""},
307+
} {
308+
test := test // capture range variable
309+
t.Run(test.name, func(t *testing.T) {
310+
t.Parallel() // Mark subtest for parallel execution.
311+
got := Transform(test.input)
312+
if diff := cmp.Diff(test.want, got); diff != "" {
313+
t.Errorf("mismatch (-want +got):\n%s", diff)
314+
}
315+
})
316+
}
317+
}
318+
```
319+
283320
## Need Help? Just Ask!
284321

285322
This guide will continue to evolve. If something feels unclear or is missing,

0 commit comments

Comments
 (0)