27

有没有办法在“测试”中获取命令行参数,
当你调用go test显然你main没有运行时,有没有办法处理命令行参数,

一种方法是使用flags包并检查每个测试或正在测试的函数中的命令行参数,但这并不理想,因为您需要在很多地方执行此操作,这与您只是在main当您运行应用程序时。

有人可能会认为这是错误的做法,并且违反了单元测试的纯洁性:

  1. 并非所有测试都是单元测试
  2. 不依赖“ENV”变量并实际在命令行中将这些东西作为参数传递是非常有用的,

作为记录,我最终init()在我的一个文件中放置了一个函数_test,并设置了在以这种方式调用 main 时通过标志设置的变量。

4

4 回答 4

14

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

var envSetting = os.Getenv("TEST_ENV")

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

func init() {
    flags.Parse()
    myEnv = *envFlag
    // ...
}
于 2014-01-25T15:10:59.083 回答
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)
    ...
}
于 2015-10-24T10:36:44.283 回答
9

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

显示一个标志和一对位置参数的简单示例

注意:不要称它为对 Go 1.8 的测试框架有特殊含义的“TestMain”。

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.
}
于 2019-11-03T10:47:29.373 回答
6
os.Args[1] = "-conf=my.conf"
flag.Parse()

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

于 2015-02-12T08:11:34.883 回答