Go的单元测试中的自定义命令行标志

时间:2014-12-07 13:14:41

标签: unit-testing go command-line-arguments

拥有模块化应用程序。有一堆测试使用一组应用程序模块,每个测试需要不同的设置。一些模块通过命令行进行调整,例如:

func init() {
    flag.StringVar(&this.customPath, "gamedir.custom", "", "Custom game resources directory")
}

但我无法测试此功能。如果我跑

go test -test.v ./... -gamedir.custom=c:/resources

运行时以

回答
flag provided but not defined: -gamedir.custom

并且未通过测试。

测试命令行参数我做错了什么?

4 个答案:

答案 0 :(得分:13)

我认为在我的情况下我得到了旗帜的错误。 使用以下命令

go test -test.v ./... -gamedir.custom=c:/resources

编译器在工作区上运行一个或多个测试。在我的特定情况下,有几个测试,因为./ ...意味着为找到的每个_test.go文件找到并创建测试可执行文件。测试可执行文件应用所有其他参数,除非其中的一个或一些被忽略。 因此,使用param的测试可执行文件通过测试,其他所有测试可执行文件都失败。这可以通过分别使用适当的参数集分别运行每个test.go的go测试来覆盖。

答案 1 :(得分:10)

如果将标志声明放在测试中,也会收到此消息。不要这样做:

func TestThirdParty(t *testing.T) {
    foo := flag.String("foo", "", "the foobar bang")
    flag.Parse()
}

而是使用init函数:

var foo string
func init() {
    flag.StringVar(&foo, "foo", "", "the foo bar bang")
    flag.Parse()
}

func TestFoo() {
    // use foo as you see fit...
}

答案 2 :(得分:2)

接受的答案,我发现并不完全清楚。为了将参数传递给测试(没有错误),您必须首先使用该标志使用该参数。对于上面的示例,其中gamedir.custom是一个传递标记,您必须在测试文件

中具有此标记

var gamedir *string = flag.String("gamedir.custom", "", "Custom gamedir.")

或将其添加到TestMain

答案 3 :(得分:2)

请注意,在Go 1.13中,如果在flag.Parse()中使用init(),则会出现以下错误

提供了

标志,但未定义:-test.timeout

要解决此问题,您必须使用TestMain

func TestMain(m *testing.M) {
    flag.Parse()
    os.Exit(m.Run())
}

TestFoo(t *testing.T) {}