-
Notifications
You must be signed in to change notification settings - Fork 18.8k
Description
(I'm increasingly seeing this problem, but I also see a lot of pragmatic benefit to testable examples. Perhaps this issue will spur discussions on how to resolve this in a more scalable way).
The Problem
In the testing package, you are allowed to append a special "Output:" comment at the end of examples such that the example will be run as a test and the output directly compared as strings (ignoring whitespace).
This feature of turning examples into tests has a lot of pragmatic benefits. It's very useful in the strings or any package that has relatively small number of dependencies on other packages. However, this feature breaks down on examples that depend on output from 3rd party packages not under the example author's control, which happens to be a dominant case at scale.
For example authors it is often not obvious that they are even depending on stable output when they write their test. For example, simply writing fmt.Println(v) inherently ties the test to the concrete implementation of v (and nested types in v) that may not be under the author's control.
Suppose v was:
type Foo struct {
...
BarField bar.Value
}Even though, v may be a type owned by the test author, bar.Value is a type that is owned by some external author (e.g., me). If I add a bar.Value.String method or change an existing String method in a package that I own, I accidentally break any tests that may have been printing my type.
The existence of testable example outputs based on strings encourages test authors to depend on this property, and makes it difficult for library maintainers at scale.
I have seen this problem repeatedly show itself time after time when any of the following packages changes it outputs: compress/*, archive/*, encoding/*, the String method on protocol buffer messages, cmp.Diff, etc.
As a library maintainer at Google, a large proportion of my engineering time is dealing with poorly written tests, and example tests are a significant offender. One of Go's goals are development scale, and example tests are hindering this goal.
Proposed Solution
As much benefit testable examples bring, I believe they bring more harm at scale, and so I propose that that we remove the ability for the testing package. However, continue to build examples.
I would love to hear alternative solutions.