argparse的python unittest [英] python unittest for argparse
问题描述
我在模块内有一个函数,可创建argparse
:
I have a function inside a module that creates an argparse
:
def get_options(prog_version='1.0', prog_usage='', misc_opts=None):
options = [] if misc_opts is None else misc_opts
parser = ArgumentParser(usage=prog_usage) if prog_usage else ArgumentParser()
parser.add_argument('-v', '--version', action='version', version='%(prog)s {}'.format(prog_version))
parser.add_argument('-c', '--config', dest='config', required=True, help='the path to the configuration file')
for option in options:
if 'option' in option and 'destination' in option:
parser.add_argument(option['option'],
dest=option.get('destination', ''),
default=option.get('default', ''),
help=option.get('description', ''),
action=option.get('action', 'store'))
return parser.parse_args()
样本myapp.py
为:
my_options = [
{
"option": "-s",
"destination": "remote_host",
"default": "127.0.0.1",
"description": "The remote server name or IP address",
"action": "store"
},
]
# Get Command Line Options
options = get_options(misc_opts=my_options)
print options.config
print options.remote_host
,这将称为:
$> python myapp.py -c config.yaml
$> config.yaml
127.0.0.1
现在,我正在尝试为此功能创建一个单元测试,但是我的问题是我无法通过测试代码传递命令行参数.
Now, I am trying to create a unit test for this function but my problem is that I can't pass command line parameters via test code.
# mytest.py
import unittest
from mymodule import get_options
class argParseTestCase(unittest.TestCase):
def test_parser(self):
options = get_options()
# ...pass the command line arguments...
self.assertEquals('config.yaml', options.config) # ofcourse this fails because I don't know how I will pass the command line arguments
我的问题是我需要将命令行参数传递给get_options()
,但是我不知道如何正确执行.
My problem is that I need to pass the command line arguments to get_options()
but I don't know how to do it properly.
预期的正确调用:python mytest.py
(-c config.yaml
应该以某种方式传递到测试代码中.)
Expected proper call: python mytest.py
(-c config.yaml
should be passed inside the test code somehow.)
什么是有效的"/目前不起作用:
What is "working"/not working right now:
-
python mytest.py -c config.yaml
也不起作用.返回AttributeError: 'module' object has no attribute 'config'
,因为它希望我改为调用argParseTestCase
.换句话说,python mytest.py -c argParseTestCase
有效",但当然会是返回值AssertionError: 'config.yaml' != 'argParseTestCase'
-
python mytest.py -v
以详细模式运行单元测试也失败.它返回:
python mytest.py -c config.yaml
is also not working. ReturnsAttributeError: 'module' object has no attribute 'config'
since it expects me to callargParseTestCase
instead. In other words,python mytest.py -c argParseTestCase
"works" but would ofcourse be an returnAssertionError: 'config.yaml' != 'argParseTestCase'
python mytest.py -v
to run the unit test in verbose mode also fails. It returns:
test_parser(主要 .argParseTestCase)... mytest.py 1.0错误 错误:test_parser(主要 .argParseTestCase)
追溯(最近一次通话): 在test_parser options = get_options()中的文件"tests/unit_tests/mytest.py",行376 get_options中的文件"/root/test/lib/python2.7/site-packages/mymodule.py",第61行,返回parser.parse_args()
在parse_args args中的文件"/usr/local/lib/python2.7/argparse.py",行1701,argv = self.parse_known_args(args,名称空间)
在parse_known_args命名空间中的文件"/usr/local/lib/python2.7/argparse.py",行1733,args = self._parse_known_args(args,命名空间)
_parse_known_args中的文件"/usr/local/lib/python2.7/argparse.py",行1939,start_index =耗用可选(start_index)
1879行中的"/usr/local/lib/python2.7/argparse.py"文件,在Consumer_Optional Take_action(action,args,option_string)中
在take_action操作(自身,名称空间,argument_values,option_string)中的文件"/usr/local/lib/python2.7/argparse.py",行1807
在调用 parser.exit(message = formatter.format_help())
中,文件"/usr/local/lib/python2.7/argparse.py",第1022行 退出_sys.exit(status)的文件"/usr/local/lib/python2.7/argparse.py",第2362行 SystemExit:0
test_parser (main.argParseTestCase) ... mytest.py 1.0 ERROR ERROR: test_parser (main.argParseTestCase)
Traceback (most recent call last): File "tests/unit_tests/mytest.py", line 376, in test_parser options = get_options() File "/root/test/lib/python2.7/site-packages/mymodule.py", line 61, in get_options return parser.parse_args()
File "/usr/local/lib/python2.7/argparse.py", line 1701, in parse_args args, argv = self.parse_known_args(args, namespace)
File "/usr/local/lib/python2.7/argparse.py", line 1733, in parse_known_args namespace, args = self._parse_known_args(args, namespace)
File "/usr/local/lib/python2.7/argparse.py", line 1939, in _parse_known_args start_index = consume_optional(start_index)
File "/usr/local/lib/python2.7/argparse.py", line 1879, in consume_optional take_action(action, args, option_string)
File "/usr/local/lib/python2.7/argparse.py", line 1807, in take_action action(self, namespace, argument_values, option_string)
File "/usr/local/lib/python2.7/argparse.py", line 1022, in call parser.exit(message=formatter.format_help())
File "/usr/local/lib/python2.7/argparse.py", line 2362, in exit _sys.exit(status) SystemExit: 0
推荐答案
我更喜欢显式传递参数,而不是依赖全局可用的属性(例如sys.argv
(parser.parse_args()
在内部执行)).因此,我通常通过自己传递参数列表来使用argparse
(传递给main()
,随后传递给get_options()
以及需要的地方):
I prefer explicitly passing arguments instead of relying on globally available attributes such as sys.argv
(which parser.parse_args()
does internally). Thus I usually use argparse
by passing the list of arguments myself (to main()
and subsequently get_options()
and wherever you need them):
def get_options(args, prog_version='1.0', prog_usage='', misc_opts=None):
# ...
return parser.parse_args(args)
然后传入参数
def main(args):
get_options(args)
if __name__ == "__main__":
main(sys.argv[1:])
这样,我就可以替换和测试我喜欢的任何参数列表
that way I can replace and test any list of arguments I like
options = get_options(['-c','config.yaml'])
self.assertEquals('config.yaml', options.config)
这篇关于argparse的python unittest的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!