2012-12-05 31 views
11

我在使用gocheck运行测试时遇到问题。我需要传递一个标志来指定运行哪个测试,例如。Golang冲突的命令行标志

我的测试文件导入了一个设置包,其中有一个init()函数,它指定了它自己的标记并调用了flag.parseFlags()。我遇到的问题是,这似乎是覆盖gocheck标志,所以我得到一个错误,标志-gocheck.f不被识别。

注意:不确定这是否相关,但它只发生在我的一些软件包中,而不发生在其他软件包中。我认为这只是基于订单决定导入软件包,但我想我会提到它,以防万一这是相关的。

有没有其他人遇到这个问题?有没有一种简单的方法可以让所有的标志合并而不会被破坏,或者让gocheck标志优先于我的自定义标志?

回答

14

如果不止一个包调用flag.Parse,而没有任何其他包定义其他标志的问题,那么你就麻烦了(正如你已经经历的那样)。 “flag”包的状态是一个全局状态,所以它或多或少就像不同的包在初始化过程中竞争将全局变量的值设置为不同的值一样。显然,这可能不会很好。

预防此问题的简单方法:flag.Parse应仅调用一次(在第一个近似值中)。这就是为什么它通常只在“main”包中看到的原因。如果您的非主包裹呼叫flag.Parse,那么它通常会与包裹“main”中调用的任何flag.Parse发生冲突。请注意,go test合成了一个package main为了测试一个包,并且从该合成的“主”包中调用了flag.Parse

另一方面,它更“安全”(但冲突是可能的),只在非主包中定义标志,依靠flag.Parse将在包“main”中调用。在非主包中,可以通过使用flag.Parsed()验证flag.Parse已被调用。

以上写的简化。有关其他选项,请检查包标志documentation。在某些情况下可以通过例如使用flag.Flagset,即通过使用本地状态来获得包内的标志选项来获得更多“功率”。然而,我个人更喜欢不以任何方式在package“main”之外使用软件包“flag”,而是通过其API设置任何可配置的软件包行为。虽然例外情况存在,例如在* _test文件或其他特殊情况下。

+2

谢谢。我实际上通过将gocheck匿名导入到我的设置文件中来修正了试验和错误的代码,现在所有的标志一起工作。在阅读你的答案并查看gocheck源代码后,我明白为什么这会起作用 - gocheck从不调用flag.Parse(),所以我只需确保gocheck在调用settings.init()方法之前就被导入,并且所有的标志都会一起工作。好的建议虽然只是解析主标记,但我会为未来记住这一点。 – danny