我的 业务单元(需要被测试的单元)中依赖了另外一个包(以下简称 parser
包),parser
包专门负责解析所有传入的命令行参数,在 parser
包的 init
函数中进行了 flag.Parse
操作,将命令行参数绑定至该包的变量内。
所有的 业务单元 需要用到命令行参数,直接从 parser
包的变量中取就行了,而不需要自己做解析。
现在,我需要对那个依赖了 parser 包中变量的业务单元进行单元测试,在执行 go test 命令的时候自然而然会将 parser 包一起编译,所以当执行测试的时候,会先执行 parser 包的 init 函数进行命令行参数解析。
现在,问题就出在这里,我无法通过命令行将参数传递测试程序,应该怎样传递?
以下是我的尝试,都报错了:flag provided but not defined: -test.timeout
➜ logger git:(master) ✗ go test logger.go logger_test.go -monitor-url=foo
flag provided but not defined: -test.timeout
Usage of /var/folders/s8/lrvd172x0_5bn35_lblgb0tm0000gn/T/go-build722317095/b001/logger.test:
-debug-mode
turn on debug mode
-mail-from-addr string
sender's mail address
-mail-from-name string
sender's name
-mail-from-password string
sender's smtp auth code
-mail-smtp-auth-host string
smtp auth host
-mail-smtp-server-addr string
smtp server addr
-mail-to-addr string
receiver's mail address
-monitor-interval string
milli second, testing cycle (default "20000")
-monitor-respheader-timeout string
milli second, timeout for waiting response header (default "2000")
-monitor-total-timeout string
milli second, timeout for waiting url response (default "5000")
-monitor-url string
the url for monitor
FAIL command-line-arguments 0.450s
FAIL
➜ logger git:(master) ✗ go test logger.go logger_test.go -args -monitor-url=foo
flag provided but not defined: -test.timeout
Usage of /var/folders/s8/lrvd172x0_5bn35_lblgb0tm0000gn/T/go-build861303357/b001/logger.test:
-debug-mode
turn on debug mode
-mail-from-addr string
sender's mail address
-mail-from-name string
sender's name
-mail-from-password string
sender's smtp auth code
-mail-smtp-auth-host string
smtp auth host
-mail-smtp-server-addr string
smtp server addr
-mail-to-addr string
receiver's mail address
-monitor-interval string
milli second, testing cycle (default "20000")
-monitor-respheader-timeout string
milli second, timeout for waiting response header (default "2000")
-monitor-total-timeout string
milli second, timeout for waiting url response (default "5000")
-monitor-url string
the url for monitor
FAIL command-line-arguments 0.313s
FAIL
➜ logger git:(master) ✗ go test logger.go logger_test.go -args monitor-url=foo
flag provided but not defined: -test.timeout
Usage of /var/folders/s8/lrvd172x0_5bn35_lblgb0tm0000gn/T/go-build447796332/b001/logger.test:
-debug-mode
turn on debug mode
-mail-from-addr string
sender's mail address
-mail-from-name string
sender's name
-mail-from-password string
sender's smtp auth code
-mail-smtp-auth-host string
smtp auth host
-mail-smtp-server-addr string
smtp server addr
-mail-to-addr string
receiver's mail address
-monitor-interval string
milli second, testing cycle (default "20000")
-monitor-respheader-timeout string
milli second, timeout for waiting response header (default "2000")
-monitor-total-timeout string
milli second, timeout for waiting url response (default "5000")
-monitor-url string
the url for monitor
FAIL command-line-arguments 0.094s
FAIL
问题已解决,原因在于,
testing
包也需要注册flags
,比如报错中的test.timeout
就是一个flag
,而理论上应该是先将所有的flags
(包括testing
包需要的和自己的程序需要的)注册之后,再执行flag.Parse
。而我的parser
包是被依赖的包,所以先被执行init
,进行了flag.Parse
操作,导致testing
包的flags
注册动作发生在Parse
之后,从而得不到注册。解决办法
分析执行测试时代码的执行顺序,只要保证在
Parse
解析之前,testing
包需要的flags
和你的程序需要的flags
都进行了注册即可。主动调用testing
包的flags
注册动作是testing.Init()
函数。