在Go测试中处理命令行参数

huangapple go评论72阅读模式
英文:

Process command line arguments in go test

问题

在Go语言的测试中,有没有办法获取命令行参数?

当你调用go test时,显然不会运行main函数,所以有没有办法处理命令行参数呢?

一种方法是使用flags包,并在每个测试或被测试的函数中检查命令行参数,但这并不理想,因为你需要在很多地方都这样做,而不像在运行应用程序时只需要在main函数中处理。

有人可能认为这样做是错误的,违背了单元测试的纯粹性:

  1. 并不是所有的测试都是单元测试。
  2. 不依赖于"ENV"变量,通过命令行参数传递参数是非常实用的。

顺便说一下,我最后在一个_test文件中放置了一个init()函数,并在调用main函数时设置了通过flags设置的变量。

英文:

Is there a way to get the command line arguments in go "tests",
When you call go test obviously your main is not run, so is there a way to process command line arguments,

One way would be to use the flags packages and check for the command line arguments in each test or function being tested, but that is not ideal for that you need to do this in lots and lots of places, unlike the way you to it just in main when you run the application.

One may think it is a wrong thing to do, and that it is against purity of unit-tests:

  1. not all tests are unit tests
  2. it is very functional not to rely on "ENV" variables and actually pass the stuff as arguments in command line,

For the record I ended up putting an init() function in one of my _test files, and set the variable that is set through flags when the main is called this way.

答案1

得分: 16

环境配置最好保存在环境变量中,根据我的经验。你可以像这样依赖全局变量:

var envSetting = os.Getenv("TEST_ENV")

或者,如果使用标志是必需的,你可以将初始化代码放在名为init()的函数中。

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

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
    // ...
}

答案2

得分: 14

你可以直接测试主函数并传递参数。

以下是一个简单的示例,展示了一个标志和一对位置参数。

注意:不要将其命名为'TestMain',因为在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()

	// 在这里进行测试结果,并决定通过/失败。
}
英文:

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.
}

答案3

得分: 9

一种替代方法是将main()函数作为一个存根,在参数被flag.Parse()处理后,仅仅调用另一个函数,例如:

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

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

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

然后在你的测试中,可以在调用submain(...)之前设置标志变量并建立参数,模拟命令行中建立标志和参数的过程。这种方法可以最大程度地提高测试覆盖率,而无需实际使用命令行。例如,在main_test.go中,你可以这样编写:

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

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)
    ...
}

答案4

得分: 6

请注意,配置文件名是硬编码的。

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

Notice that the config file name is hard-coded.

huangapple
  • 本文由 发表于 2014年1月25日 21:08:56
  • 转载请务必保留本文链接:https://go.coder-hub.com/21350962.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定