init() and tests

14,910 views
Skip to first unread message

Alex Efros

unread,
Sep 11, 2015, 5:56:31 PM9/11/15
to golan...@googlegroups.com
Hi!

Is there any recommendations about how to use init() functions, especially
taking in account tests?

As far as I see, init() in *_test.go run after non-test files, so
lexicographical order mentioned in spec is somewhat violated.
Because of this it's impossible to ensure tests will have a chance to run
own init() before any other init() - and this make testing init()
functions very hard.

For example, our packages often read config files in init() because values
from these files are needed to initialize global vars or do other
initialization tasks like connecting to log service.
Is this way to use init() functions considered harmful and should be avoided?
If not, then how to get a chance in tests to fake contents of config files
(we often need to do this in tests) before all these init() functions will
run and read real config files?

--
WBR, Alex.

nicolas riesch

unread,
Sep 11, 2015, 6:12:18 PM9/11/15
to golang-nuts

parais...@gmail.com

unread,
Sep 11, 2015, 8:42:44 PM9/11/15
to golang-nuts
You can use 

// +build !testing


pragma right before an init function in order to disable it for tests.

Roberto Zanotto

unread,
Sep 11, 2015, 9:04:49 PM9/11/15
to golang-nuts
If you want to test some init procedure, I'd suggest you to rewrite the init like this:
func init() {
   someFunc(real parameters)
}
And then you can run tests on someFunc(fake parameters).

Alex Efros

unread,
Sep 11, 2015, 10:12:04 PM9/11/15
to golang-nuts
Hi!

On Fri, Sep 11, 2015 at 05:42:26PM -0700, parais...@gmail.com wrote:
> You can use
>
> // +build !testing
>
> pragma right before an init function in order to disable it for tests.

Is this documented somewhere? I've tried to find build tag related to
building tests, but failed. This one doesn't work for me too (go-1.4.2).

--
WBR, Alex.

Alex Efros

unread,
Sep 11, 2015, 10:20:27 PM9/11/15
to golang-nuts
Hi!

On Fri, Sep 11, 2015 at 03:12:18PM -0700, nicolas riesch wrote:
> I had a similar problem:
> https://groups.google.com/forum/#!searchin/golang-nuts/nicolas.riesch/golang-nuts/eNRM1ujLtZ0/6BqevVwuOkcJ

Thanks! That thread mention nice workaround, which actually works:

// in *_test.go:

var _ = func() (_ struct{}) {
fmt.Println("This runs before init()!")
return
}()

> See TestMain function in https://golang.org/pkg/testing/

This won't help - TestMain() runs after init().

--
WBR, Alex.

nicolas riesch

unread,
Sep 12, 2015, 7:39:18 AM9/12/15
to golang-nuts
Documentation about "build constraint" +build:



Alex Efros

unread,
Sep 12, 2015, 7:45:20 AM9/12/15
to nicolas riesch, golang-nuts
Hi!

On Sat, Sep 12, 2015 at 04:39:17AM -0700, nicolas riesch wrote:
> Documentation about "build constraint" +build:
>
> https://golang.org/pkg/go/build/

I know. But there is nothing about constraint related to `go test`.

--
WBR, Alex.

Alex Efros

unread,
Sep 12, 2015, 9:15:31 AM9/12/15
to golang-nuts
Hi!

On Fri, Sep 11, 2015 at 06:04:49PM -0700, Roberto Zanotto wrote:
> If you want to test some init procedure, I'd suggest you to rewrite the
> init like this:
> func init() {
> someFunc(real parameters)
> }
> And then you can run tests on someFunc(fake parameters).

We already doing this, but it's not enough. To make it really useful in
tests that someFunc() should completely reset package's state -
re-initialize all global vars, etc. This way tests will be able to call it
(and even call it multiple times when needed) to override everything what
was done by init() functions.

--
WBR, Alex.

Alexandre Fiori

unread,
Sep 12, 2015, 8:25:11 PM9/12/15
to golang-nuts
Have you looked at TestMain?

You can do all your setup and teardown in any way you want.
Reply all
Reply to author
Forward
0 new messages