Process command line arguments in go test

Environmental configs are best kept in environment variables, in my experience. You can rely on global variables like so:

var envSetting = os.Getenv("TEST_ENV")

Alternatively, if using flags is a requirement, you could place your initialization code inside a function called init().

func init() {
    flags.Parse()
    myEnv = *envFlag
    // ...
}

You can directly test main function and pass arguments.

Simple example showing a flag, and a pair of positional arguments

Note: Do NOT call it 'TestMain' that has a special meaning to the testing framework as of Go 1.8.

package main

import (
    "os"
    "testing"
)

func TestMainFunc(t *testing.T) {

    os.Args = append(os.Args, "--addr=http://b.com:566/something.avsc")
    os.Args = append(os.Args, "Get")
    os.Args = append(os.Args, `./some/resource/fred`)

    main()

    // Test results here, and decide pass/fail.
}

An alternative approach is to make main() be a stub that merely calls into another function after arguments are processed by flag.Parse(), for example:

var flagvar int
func init() {
    flag.IntVar(&flagvar, "flagname", 1234, "help for flagname")
}

func main() {
    flag.Parse()
    submain(flag.Args)
}

func submain(args []string) {
   ...
}

Then in your tests, flag variables can be set and arguments established before calling submain(...) simulating the command line establishment of flags and arguments. This approach can be used to maximize test coverage without actually using a command line. For example, in main_test.go, you might write:

func TestSomething(t *testing.T) {
    flagvar = 23
    args := []string{"a", "b", "c"}
    submain(args)
    ...
}

os.Args[1] = "-conf=my.conf"
flag.Parse()

Notice that the config file name is hard-coded.