golang / go

The Go programming language
https://go.dev
BSD 3-Clause "New" or "Revised" License
123.59k stars 17.61k forks source link

testing: _test package runs init() in the containing folder #58823

Closed bep closed 1 year ago

bep commented 1 year ago

I'm having problems finding good documentation about the expected behaviour of the _test package, but as I was bitten/surprised by this, it should warrant at least a searchable issue.

See the project and failing test in https://github.com/bep/gotestpackageinit/blob/main/pkga/int_test.go#L1

The test fails because the init() func in pkga panics (which is a little constructed, I agree).

My understanding is that pkga_test would be compiled as a separate package and that I could only access pkga's exported identifiers and only with an explicit import of that package.

In my case I had a great and working integration test of a feature that failed mysteriously in the production binary because the init() was never called.

https://github.com/gohugoio/hugo/issues/10774

seankhliao commented 1 year ago

From go help test:

Test files that declare a package with the suffix "_test" will be compiled as a separate package, and then linked and run with the main test binary.

While _test is compiled as a separate package, the test binary itself, including the setup/teardown is run in the context of the main package, so it will always be included. This is apparent if you write tests in both packages and compile the test binary: you only get one.

Closing as both working as intended and documented

bep commented 1 year ago

While _test is compiled as a separate package, the test binary itself, including the setup/teardown is run in the context of the main package, so it will always be included.

@seankhliao I have read your comment twice, and I'm getting even more confused than before I wrote this issue. What main package do you talk about? I have a pkga_test (which gets compiled as a separate package) that invokes a exported method in pkgb.

Test files that declare a package with the suffix "_test" will be compiled as a separate package, and then linked and run with the main test binary.

There's nothing in the above that suggests the current surprising behaviour – and I'm not thrilled that my issue is brushed off so lightly.

seankhliao commented 1 year ago

The test binary is constructed in the context of pkga, even if it contains no tests. Anything in pkga_test are just an additional set of tests to be included. Initialization is property of the program, not the package, so init is always called.