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

yrdbyhpb  于 12个月前  发布在  Go
关注(0)|答案(5)|浏览(114)

有没有一种方法可以在go“测试”中获得命令行参数,
当你调用go test时,显然你的main没有运行,那么有没有一种方法来处理命令行参数,
一种方法是使用flags包并检查每个测试或正在测试的函数中的命令行参数,但这并不理想,因为您需要在很多很多地方这样做,而不像在运行应用程序时仅在main中这样做。
有人可能认为这是一件错误的事情,而且这是违反单元测试的纯洁性的:
1.并非所有测试都是单元测试
1.不依赖于“ENV”变量并实际在命令行中将其作为参数传递是非常实用的,
为了记录在案,我最后把一个init()函数放在我的一个_test文件中,并设置变量,当以这种方式调用main时,该变量通过标志来设置。

kuhbmx9i

kuhbmx9i1#

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

var envSetting = os.Getenv("TEST_ENV")

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

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

at0kjp5o2#

你可以直接测试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.
}
5cg8jx4n

5cg8jx4n3#

另一种方法是让main()成为一个stub,在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)
    ...
}
lsmepo6l

lsmepo6l4#

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

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

bwntbbo3

bwntbbo35#

当我在测试设置中使用init()来解析标志时,我发现了jbowen's post,它提供了一种在测试运行中访问传入标志的更简单的方法,这是基于flag.Parse()已经由go test执行的事实。

var stringArg = flag.String("my-arg", "default", "value for my-arg")

这需要在包作用域中定义,以便标志模块在解析之前提取它。否则,它为您提供了对额外定义的标志的轻松访问,我想它可以在可重用的测试夹具包中定义。

相关问题