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

Ali*_*Ali 18 testing go command-line-arguments go-flag

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

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

编辑:主要是向下选民,我想你是在贬低这个问题,因为你认为这是一个错误的事情,并且反对单位测试的纯度,

  1. 并非所有测试都是单元测试
  2. 它非常实用,不依赖于"ENV"变量,实际上将这些东西作为参数传递给命令行,
  3. 请将您的意见放在答案中,以便后代能够受益,

编辑2:为了记录,我最终init()在我的一个_test文件中放置了一个函数,并设置了通过这种方式调用main时通过flags设置的变量.

Sam*_* II 10

根据我的经验,环境变量最好保存在环境变量中.您可以依赖全局变量,如下所示:

var envSetting = os.Getenv("TEST_ENV")
Run Code Online (Sandbox Code Playgroud)

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

func init() {
    flags.Parse()
    myEnv = *envFlag
    // ...
}
Run Code Online (Sandbox Code Playgroud)

  • @MatrixFrog - 您只是在猜测或发表声明吗?那些信息是错误的.我在自己的测试中使用`init`就好了,为整个过程设置一些全局测试资源. (3认同)
  • 我编写了一个测试来验证测试时是否未调用init().但我做错了 - 你是对的,仍然会调用init().对不起,没关系! (3认同)

小智 7

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

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

注意:不要将其称为“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()

    // Test results here, and decide pass/fail.
}
Run Code Online (Sandbox Code Playgroud)


小智 5

os.Args[1] = "-conf=my.conf"
flag.Parse()
Run Code Online (Sandbox Code Playgroud)

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

  • 如果 cli 没有传递任何参数,这将引发索引超出范围错误。显式覆盖 os.Args []string 可能是更好的选择。`os.Args = []string{"noop", "-flag1=val1", "arg1", "arg2"}` (2认同)

paj*_*to0 5

另一种方法是使它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) {
   ...
}
Run Code Online (Sandbox Code Playgroud)

然后在测试中,可以在调用submain(...)模拟标志和参数的命令行建立之前设置标志变量并建立参数。此方法可用于最大化测试覆盖范围,而无需实际使用命令行。例如,在main_test.go中,您可以编写:

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