init() in test file should run after other init() ?

3,070 views
Skip to first unread message

nicolas riesch

unread,
Aug 16, 2015, 3:24:54 PM8/16/15
to golang-nuts
I have an init() function in a package.
In same package, I have a test file (that imports "testing") with also an init() function, because I want to initialize some global variables used by the test functions.

The problem is that init() in test file runs before init() in package.

Is there a means to make the init() in test file run after init() of the package ?

Or is it desirable that Go runs init() in test file AFTER all the other init() ?

Roberto Zanotto

unread,
Aug 16, 2015, 3:52:37 PM8/16/15
to golang-nuts
From the spec:
A package (with no imports) is initialized by assigning initial values to all its package-level variables followed by calling all init functions in the order they appear in the source, possibly in multiple files, as presented to the compiler.

So it depends on compilation order. I can't find guarantees about compilation order in the go command documentation and it should be possible to pass the go files to "go build" in such a way that the order can be changed. So you'd better avoid depending on the order if you can (as far as I can understand from the documentation).
By the way, you can rely on the fact that global variables initialized outside the init function will be initialized before calling init().

nicolas riesch

unread,
Aug 16, 2015, 4:14:07 PM8/16/15
to golang-nuts
The _test.go files for "testing" are technically in the same package being tested.
But practically, they seem to belong more to a "main" package. When you write test functions, you expect that all initialization of the package being tested has been done.
It can be surprising if it is not the case. The intra package dependency is that _test.go files depends on the other files, not the converse.

So, would it be reasonable to fill an issue to force init() in _test.go files run last ?


Message has been deleted

Dave Cheney

unread,
Aug 16, 2015, 6:41:22 PM8/16/15
to golang-nuts
I don't believe that change would be accepted.

A better solution may be to use something like sync.Once to handle initialisation of some shared test fixture.

You could also take advantage of the fact that tests are run in lexical order, so (untested) you could place this logic in a TestAAAA function.

A third option is to use the TestMain support added in Go 1.4 to run your initialisation before any tests are run. This has the advantage that this initialisation cannot be skipped if you use the -test.run filter.

Thanks

Dave

Roberto Zanotto

unread,
Aug 16, 2015, 7:00:24 PM8/16/15
to golang-nuts

Roberto Zanotto

unread,
Aug 16, 2015, 8:38:51 PM8/16/15
to golang-nuts
I agree with you, it is reasonable to expect the package to be fully initialized before initializing the tests/benchmarks of the package itself. "Fixing" this would not break existing code. But, it would require to change the spec adding the additional order guarantee and to fix the build system. Other implementations of the language, like gccgo, would have to do the same thing. I don't see that happening easily, also because there are easy workarounds.

Daniel Theophanes

unread,
Aug 16, 2015, 9:20:39 PM8/16/15
to golang-nuts
init funcs should never rely on order. Use TestMain for order dependent init.
Reply all
Reply to author
Forward
0 new messages