11

我在使用gocheck运行测试时遇到问题。我需要向它传递一个标志来指定要运行的测试,例如go test -gocheck.f ApiSuite.TestSomeFunction.

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

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

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

4

1 回答 1

14

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

防止这种情况的简单方法:flag.Parse应该只调用一次(在第一个近似值中)。这就是为什么它通常只出现在包“main”中的原因。如果您的非主包调用flag.Parse,那么它通常会与flag.Parse包“主”中的任何调用冲突。请注意,go test合成 apackage main是为了测试包,并从合成的“主”包flag.Parse 中调用。

另一方面,仅在非主包中定义标志并依赖flag.Parse将在包“main”中调用更“安全”(但无论如何都可能发生冲突)。在非主包中,可以使用flag.Parsed()flag.Parse验证是否已被调用。

上面写的简化的。有关其他选项,请查看包标志文档。在某些情况下,可以通过例如使用flag.Flagset来获得更多“权力” ,即通过使用本地状态作为包内的标志选项。

但是,我个人不喜欢以任何方式在包“main”之外使用包“标志”,而是通过其 API 设置任何可配置的包行为。但是,确实存在例外,例如在 *_test 文件或其他特殊情况中。

于 2012-12-05T06:58:22.803 回答