英文:
Custom command line flags in Go's unit tests
问题
有一个模块化的应用程序。有一堆使用一组应用程序模块的测试,每个测试需要不同的模块集。一些模块通过命令行进行调整,例如:
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
并且测试失败。
我在测试命令行参数方面做错了什么?
英文:
Have a moduled application. Have a bunch of tests that use a set of application modules, each test requires different set. Some modules are tuned through the command-line, e.g:
func init() {
flag.StringVar(&this.customPath, "gamedir.custom", "", "Custom game resources directory")
}
But I cannot test this functionality. If I run
go test -test.v ./... -gamedir.custom=c:/resources
the runtime answers with
flag provided but not defined: -gamedir.custom
and fails the test.
What am I doing wrong with testing command-line args?
答案1
得分: 19
我想我明白了,在我的情况下,标志出了什么问题。
使用以下命令:
go test -test.v ./... -gamedir.custom=c:/resources
编译器在工作区上运行一个或多个测试。在我特定的情况下,有多个测试,因为"./..."表示查找并为找到的每个_test.go文件创建测试可执行文件。测试可执行文件将应用所有附加参数除非其中一个或多个在其中被忽略。
因此,使用参数的测试可执行文件通过测试,而其他所有测试失败。可以通过为每个test.go分别运行go test,并使用相应的参数集来覆盖这一点。
英文:
I think I got it what is wrong with flags in my case.
With the following command
go test -test.v ./... -gamedir.custom=c:/resources
the compiler runs one or several tests on a workspace. In my particular case there are several tests, because ./... means find and create test executable for every _test.go file found. The test executable applies all the additional params unless one or some of them is ignored within it.
Thus the test executables that do use param pass the test, all others fail. This may be overridden by running go test for each test.go separately, with appropriate set of params respectively.
答案2
得分: 13
你也会收到这个消息,如果你把标志声明放在一个测试中。不要这样做:
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() {
// 根据需要使用foo...
}
英文:
You'll also get this message if you put your flag declarations inside of a test. Don't do this:
func TestThirdParty(t *testing.T) {
foo := flag.String("foo", "", "the foobar bang")
flag.Parse()
}
Instead use the init function:
var foo string
func init() {
flag.StringVar(&foo, "foo", "", "the foo bar bang")
flag.Parse()
}
func TestFoo() {
// use foo as you see fit...
}
答案3
得分: 5
接受的答案,我发现并不完全清楚。为了传递一个参数给一个测试(而不出错),你必须首先使用标志来消耗该参数。对于上面的例子,其中gamedir.custom是一个传递的标志,你必须在你的测试文件中添加以下内容:
var gamedir *string = flag.String("gamedir.custom", "", "自定义游戏目录。")
或者将其添加到TestMain
中。
英文:
The accepted answer, I found wasn't completely clear. In order to pass a parameter to a test (without an error) you must first consume that parameter using the flag. For the above example where gamedir.custom is a passed flag you must have this in your test file
var gamedir *string = flag.String("gamedir.custom", "", "Custom gamedir.")
Or add it to the TestMain
答案4
得分: 4
请注意,从Go 1.13开始,如果在init()
函数中使用flag.Parse()
,你将会得到以下错误:
flag provided but not defined: -test.timeout
要解决这个问题,你需要使用TestMain
函数:
func TestMain(m *testing.M) {
flag.Parse()
os.Exit(m.Run())
}
TestFoo(t *testing.T) {}
希望对你有帮助!
英文:
Note that from Go 1.13, you'll get the following error if you use flag.Parse()
in init()
> flag provided but not defined: -test.timeout
To fix this, you have to use TestMain
func TestMain(m *testing.M) {
flag.Parse()
os.Exit(m.Run())
}
TestFoo(t *testing.T) {}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论