Skip to content

Commit 1052896

Browse files
authored
go: Export the latest version of internal guide. (#912)
The updates encompass renaming testing-associated package's section heading, guidance on when to panic, and naming of subtests.
1 parent 8e44515 commit 1052896

2 files changed

Lines changed: 70 additions & 13 deletions

File tree

go/best-practices.md

Lines changed: 52 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -165,7 +165,7 @@ methods:
165165

166166
<a id="naming-doubles"></a>
167167

168-
### Test double packages and types
168+
### Test double and helper packages
169169

170170
There are several disciplines you can apply to [naming] packages and types that
171171
provide test helpers and especially [test doubles]. A test double could be a
@@ -1241,11 +1241,47 @@ Another case in which panics can be useful, though uncommon, is as an internal
12411241
implementation detail of a package which always has a matching recover in the
12421242
callchain. Parsers and similar deeply nested, tightly coupled internal function
12431243
groups can benefit from this design, where plumbing error returns adds
1244-
complexity without value. The key attribute of this design is that these panics
1245-
are never allowed to escape across package boundaries and do not form part of
1246-
the package's API. This is typically accomplished with a top-level deferred
1247-
recover that translates a propagating panic into a returned error at the public
1248-
API surfaces.
1244+
complexity without value.
1245+
1246+
The key attribute of this design is that these **panics are never allowed to
1247+
escape across package boundaries** and do not form part of the package's API.
1248+
This is typically accomplished with a top-level deferred function that uses
1249+
`recover` to translate a propagated panic into a returned error at the public
1250+
API boundary. It requires the code that panics and recovers to distinguish
1251+
between panics that the code raises itself and those that it doesn't:
1252+
1253+
```go
1254+
// Good:
1255+
type syntaxError struct {
1256+
msg string
1257+
}
1258+
1259+
func parseInt(in string) int {
1260+
n, err := strconv.Atoi(in)
1261+
if err != nil {
1262+
panic(&syntaxError{"not a valid integer"})
1263+
}
1264+
}
1265+
1266+
func Parse(in string) (_ *Node, err error) {
1267+
defer func() {
1268+
if p := recover(); p != nil {
1269+
sErr, ok := p.(*syntaxError)
1270+
if !ok {
1271+
panic(p) // Propagate the panic since it is outside our code's domain.
1272+
}
1273+
err = fmt.Errorf("syntax error: %v", sErr.msg)
1274+
}
1275+
}()
1276+
... // Parse input calling parseInt internally to parse integers
1277+
}
1278+
```
1279+
1280+
> **Warning:** Code employing this pattern must take care to manage any
1281+
> resources associated with the code run in such defer-managed sections (e.g.,
1282+
> close, free, or unlock).
1283+
>
1284+
> See: [Go Tip #81: Avoiding Resource Leaks in API Design]
12491285
12501286
Panic is also used when the compiler cannot identify unreachable code, for
12511287
example when using a function like `log.Fatal` that will not return:
@@ -1270,6 +1306,16 @@ If you must die in a package initialization function (an `init` or a
12701306
["must" function](decisions#must-functions)), a panic is acceptable in place of
12711307
the fatal logging call.
12721308

1309+
See also:
1310+
1311+
* [Handling panics](https://go.dev/ref/spec#Handling_panics) and
1312+
[Run-time Panics](https://go.dev/ref/spec#Run_time_panics) in the language
1313+
specification
1314+
* [Defer, Panic, and Recover](https://go.dev/blog/defer-panic-and-recover)
1315+
* [On the uses and misuses of panics in Go](https://eli.thegreenplace.net/2018/on-the-uses-and-misuses-of-panics-in-go/)
1316+
1317+
[Go Tip #81: Avoiding Resource Leaks in API Design]: https://google.github.io/styleguide/go/index.html#gotip
1318+
12731319
<a id="documentation"></a>
12741320

12751321
## Documentation

go/decisions.md

Lines changed: 18 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,8 +96,15 @@ must be renamed at import time to a name that is suitable for use in Go code.
9696
An exception to this is that package names that are only imported by generated
9797
code may contain underscores. Specific examples include:
9898

99-
* Using the `_test` suffix for an external test package, for example an
100-
integration test
99+
* Using the `_test` suffix for unit tests that only exercise the exported API
100+
of a package (package `testing` calls these
101+
["black box tests"](https://pkg.go.dev/testing)). For example, a package
102+
`linkedlist` must define its black box unit tests in a package named
103+
`linkedlist_test` (not `linked_list_test`)
104+
105+
* Using underscores and the `_test` suffix for packages that specify
106+
functional or integration tests. For example, a linked list service
107+
integration test could be named `linked_list_service_test`
101108

102109
* Using the `_test` suffix for
103110
[package-level documentation examples](https://go.dev/blog/examples)
@@ -3401,11 +3408,15 @@ command line for users of test filtering. When you use `t.Run` to create a
34013408
subtest, the first argument is used as a descriptive name for the test. To
34023409
ensure that test results are legible to humans reading the logs, choose subtest
34033410
names that will remain useful and readable after escaping. Think of subtest
3404-
names more like a function identifier than a prose description. The test runner
3405-
replaces spaces with underscores, and escapes non-printing characters. If your
3406-
test data benefits from a longer description, consider putting the description
3407-
in a separate field (perhaps to be printed using `t.Log` or alongside failure
3408-
messages).
3411+
names more like a function identifier than a prose description.
3412+
3413+
The test runner replaces spaces with underscores, and escapes non-printing
3414+
characters. To ensure accurate correlation between test logs and source code, it
3415+
is recommended to avoid using these characters in subtest names.
3416+
3417+
If your test data benefits from a longer description, consider putting the
3418+
description in a separate field (perhaps to be printed using `t.Log` or
3419+
alongside failure messages).
34093420
34103421
Subtests may be run individually using flags to the [Go test runner] or Bazel
34113422
[test filter], so choose descriptive names that are also easy to type.

0 commit comments

Comments
 (0)