-
Notifications
You must be signed in to change notification settings - Fork 17.9k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Proposal: automatically set a "test" tag during "go test" #14668
Comments
I don't understand this at all. If the file ends "_test.go" then as far as I can tell the meaning is exactly the same as if you have a "test" build tag as proposed here. |
Without the build tag you can't do |
But you don't need that. If you put the code that belongs only to the test in a file suffixed _test.go, it is as far as I can reason exactly the same behavior as adding a test build tag. Conversely, files not suffixed _test.go are equivalent to those tagged !test, assuming we're talking about the go test command, which we are. |
Note that a "test" build tag in a separate package P imported by the package being tested, T, will have no bearing on the build of P if you run "go test" in T. You would have to first "go install" a version of P with the tag set, which means that the tag is never present when "go test" is running for T. |
I take it that it's primarily so that rather than
you could do
the same way you would define different versions of the same function in, for example, Secondarily. the proposal seems to be so that if package T imports P it also gets the Having APIs of imported packages change semantics during testing seems like an invitation for fragile and poorly thought out tests. |
It seems you're suggesting to add per- package build tag called gotest.
It will be very confusing to users. As the behavior is subtly different
between go test and go build -tags gotest. The former only applies the
build tag to the package under test whereas the later applies the build tag
to all packages it builds.
|
@robpike, @minux: I was naively thinking that the effect of the tag would propagate in the transitive closure of dependencies, but if that's not the case then that kills the idea of also relying on the built-in test tag for test-only libraries. I'm not going to suggest that build tags behave entirely different under @jimmyfrasche: In the second use case the idea wasn't to have APIs that change semantics during testing, but rather to make some APIs usable only during testing (to help prevent having production code depend on test libraries). But as mentioned above, it doesn't look like what I was suggesting would work anyway. On Sun, Mar 6, 2016 at 4:49 PM, Rob Pike wrote:
They're not equivalent since files not suffixed |
I see the distinction now. It's very subtle, maybe too subtle. In any case, there are as you point out existing mechanisms to do this. While they are not particularly elegant, they do serve. Still, the lack of tag propagation may be fatal to this proposal. |
The propagation isn't necessary for the first use case that motivated me to propose this change, namely making it easier to stub out certain functions when testing a given package. You're right that this can be achieved today, albeit with usability issues. I wasn't trying to suggest something fundamentally new, merely an improvement to the user experience by creating a standard build tag used during testing so that people/tools don't have to know what tags to pass to |
To me, it seems like an anti-pattern for your tests to execute different code than the code that runs normally. Making this feasible globally seems like a dangerous path to take. I vote no. |
I am too worried about the consequences of packages changing behavior when testing is enabled globally. Thanks for your proposal, but no. |
This is a proposal for a change to
go test
. The goal is to make it easier to enable conditional compilation of test-only code, which is useful to stub out code during testing, by introducing a build tag that is automatically set duringgo test
, similarly to how therace
tag is automatically added for builds that use the-race
flag.For example, let's say we have some code that uses the
unix.Setns()
system call, which is a Linux-specific privileged system call (usually requiresroot
or some elevated privileges likeCAP_SYS_ADMIN
). One way to make such code testable independently of the platform and privilege level is to do:This way unit tests can override the call by changing the layer of indirection that the global variable creates:
However this is a bit tedious to do, it creates an unnecessary level of indirection in the production code and clutters the test code. Another solution that addresses this is to use a build tag instead:
The downside is that now
go test ./...
doesn't work anymore, one needs to know to pass-tags test
. In a large codebase, people choose to use different build tags to implement this mechanism, which leads to inconsistencies, unlessMakefile
s (or equivalent) are used andgo test
is not to be run "manually".Another place where a built-in
test
tag could be useful is when factoring out test libraries. Code infoo_test.go
files is only visible in the current package and can't be imported from one package to another. Therefore it's common to create atest
package to factor out test code re-used across packages. Doing this unfortunately creates room for production code importing test code. By flagging the test code with a build tag, this possibility is significantly reduced. But again, the build tag creates a usability issue.There are a number of packages that already use a
test
tag (see for example the GitHub search forlanguage:go "// +build test" filename:_test.go
). Some of these packages would benefit from the usability improvement (for examplegolang.org/x/text
does not use aMakefile
butunicode/norm/forminfo_test.go
assumes thetest
tag is used), other packages would start behaving differently (for example github.com/netrack/netrack-server would start running both the integration tests and the unit tests whenmake integration-test
is run, instead of just the integration tests as the intent of theMakefile
appears to be).Alternatively the built-in tag could be
gotest
, which doesn't seem to be used on GitHub.Looking forward to your feedback on this small proposal. Thanks in advance.
The text was updated successfully, but these errors were encountered: