从unittest测试调用时,argparse失败 [英] argparse fails when called from unittest test
问题描述
在文件中(例如parser.py
),我有:
In a file (say parser.py
) I have:
import argparse
def parse_cmdline(cmdline=None):
parser = argparse.ArgumentParser()
parser.add_argument('--first-param',help="Does foo.")
parser.add_argument('--second-param',help="Does bar.")
if cmdline is not None:
args = parser.parse_args(cmdline)
else:
args = parser.parse_args()
return vars(args)
if __name__=='__main__':
print parse_cmdline()
可以肯定的是,当从命令行调用它时,它可以正常工作,并且可以给我很多我所期望的东西:
Sure enough, when called from the command line it works and give me pretty much what I expect:
$ ./parser.py --first-param 123 --second-param 456
{'first_param': '123', 'second_param': '456'}
但是随后我想unittest
它,因此我写了一个test_parser.py
文件:
But then I want to unittest
it, thus I write a test_parser.py
file:
import unittest
from parser import parse_cmdline
class TestParser(unittest.TestCase):
def test_parse_cmdline(self):
parsed = parse_cmdline("--first-param 123 --second-param 456")
self.assertEqual(parsed['first_param'],'123')
self.assertEqual(parsed['second_param'],'456')
if __name__ == '__main__':
unittest.main()
然后我得到以下错误:
usage: test_parser.py [-h] [--first-param FIRST_PARAM]
[--second-param SECOND_PARAM]
test_parser.py: error: unrecognized arguments: - - f i r s t - p a r a m 1 2 3 - - s e c o n d - p a r a m 4 5 6
E
======================================================================
ERROR: test_parse_cmdline (__main__.TestParser)
----------------------------------------------------------------------
Traceback (most recent call last):
File "./test_parser.py", line 8, in test_parse_cmdline
parsed = parse_cmdline("--first-param 123 --second-param 456")
File "/home/renan/test_argparse/parser.py", line 12, in parse_cmdline
args = parser.parse_args(cmdline)
File "/usr/lib/python2.7/argparse.py", line 1691, in parse_args
self.error(msg % ' '.join(argv))
File "/usr/lib/python2.7/argparse.py", line 2361, in error
self.exit(2, _('%s: error: %s\n') % (self.prog, message))
File "/usr/lib/python2.7/argparse.py", line 2349, in exit
_sys.exit(status)
SystemExit: 2
----------------------------------------------------------------------
Ran 1 test in 0.004s
FAILED (errors=1)
可以看出,我指定的命令行(--first-param 123 --second-param 456
)变成了
- - f i r s t - p a r a m 1 2 3 - - s e c o n d - p a r a m 4 5 6
(每个字符用空格分隔).
As can be seen, the command line I specified (--first-param 123 --second-param 456
) became
- - f i r s t - p a r a m 1 2 3 - - s e c o n d - p a r a m 4 5 6
(each character is separated by a space).
我不明白为什么:我做错了什么?
I don't understand why: what am I doing wrong?
推荐答案
argparse
希望有一个参数向量"(即单独的参数列表),而不是命令行"字符串.
argparse
wants an "argument vector"—that is, a list of separate arguments—not a "command line" string.
仅调用split
不会解决问题.例如,从命令行输入以下命令行:
And just calling split
won't solve things. For example, this command line from the shell:
python script.py --first-param '123 456' --second-param 789
…可以正确地给您123 456
和789
,但这行代码是
… will correctly give you 123 456
and 789
, but this line of code:
parse_cmdline("--first-param '123 456' --second-param 789")
不会;它将为您提供'123
和789
,还有一个额外的456'
,它不知道如何处理.
will not; it will give you '123
and 789
, with an extra 456'
that it doesn't know how to deal with.
事实上,即使这是错误的:
In fact, even this is wrong:
parse_cmdline("--first-param '123' --second-param 789")
...因为您将获得'123'
而不是123
.
… because you'll get '123'
instead of 123
.
有两种处理方法.
首先,如果您知道要传递的内容,则可以仅将其作为列表而不是字符串进行传递,并且无需担心引用和拆分细节:>
First, if you know what you're trying to pass, you can just pass it as a list instead of a string in the first place, and you don't need to worry about fiddly quoting and splitting details:
parse_cmdline(["--first-param", "123 456", "--second-param", "789"])
或者,如果您不完全知道要传递的内容,则只知道它在外壳上的外观,则可以使用
Alternatively, if you don't know exactly what you're trying to pass, you just know what it looks like on the shell, you can use shlex
:
if cmdline is not None:
args = parser.parse_args(shlex.split(cmdline))
…,现在Python将以与标准Unix shell相同的方式拆分命令行,将123 456
作为单个参数.
… and now Python will split your command line the same way as a standard Unix shell, getting the 123 456
as a single parameter.
这篇关于从unittest测试调用时,argparse失败的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!