我正在为 argparse 实现编写测试用例。我打算测试'-h'功能。下面的代码做到了。但它也输出脚本的用法。有没有办法抑制它?
self.assertRaises(SystemExit, arg_parse_obj.parse_known_args, ['-h'])
另外,我们可以检查抛出的异常号吗?例如 '-h' 抛出SystemExit: 0,而无效或不足的参数抛出SystemExit: 2。有没有办法检查数字代码?
我正在为 argparse 实现编写测试用例。我打算测试'-h'功能。下面的代码做到了。但它也输出脚本的用法。有没有办法抑制它?
self.assertRaises(SystemExit, arg_parse_obj.parse_known_args, ['-h'])
另外,我们可以检查抛出的异常号吗?例如 '-h' 抛出SystemExit: 0,而无效或不足的参数抛出SystemExit: 2。有没有办法检查数字代码?
测试异常代码时,self.assertRaises()
用作上下文管理器;这使您可以访问引发的异常,让您测试.code
属性:
with self.assertRaises(SystemExit) as cm:
arg_parse_obj.parse_known_args(['-h'])
self.assertEqual(cm.exception.code, 0)
要“抑制”或测试输出,您必须捕获sys.stdout
或sys.stderr
,具体取决于argparse
输出(帮助文本转到stdout
)。您可以为此使用上下文管理器:
from contextlib import contextmanager
from StringIO import StringIO
@contextmanager
def capture_sys_output():
capture_out, capture_err = StringIO(), StringIO()
current_out, current_err = sys.stdout, sys.stderr
try:
sys.stdout, sys.stderr = capture_out, capture_err
yield capture_out, capture_err
finally:
sys.stdout, sys.stderr = current_out, current_err
并将它们用作:
with self.assertRaises(SystemExit) as cm:
with capture_sys_output() as (stdout, stderr):
arg_parse_obj.parse_known_args(['-h'])
self.assertEqual(cm.exception.code, 0)
self.assertEqual(stderr.getvalue(), '')
self.assertEqual(stdout.getvalue(), 'Some help value printed')
我在这里嵌套了上下文管理器,但在 Python 2.7 和更新版本中,您也可以将它们组合成一行;不过,这往往会很快超过建议的 79 个字符限制。
Mock 可以做到这一点,允许您使用与 Martijn Pieters 的答案相同的功能,但无需编写自己的函数:
from unittest.mock import MagicMock, patch
argparse_mock = MagicMock()
with patch('argparse.ArgumentParser._print_message', argparse_mock):
with self.assertRaises(SystemExit) as cm:
arg_parse_obj.parse_known_args(['-h'])
patch 也可以作为装饰器。如果您有几个需要抑制 argparse 打印的实例,您可以将其作为装饰器来执行,并避免使用一堆嵌套的 with 语句。
使用的一些变化['-h']
包括:
parser.print_help() # formats the help, prints it and exits
parser.format_help() # format the help without printing or exit
parser.exit # can be modified to not exit, such as for a parser subclass
parser.error # default print usage and call parser.exit
这些是公共 API 的一部分。
argparse
测试文件 ( test_argparse.py
) 还提供了有关如何测试事物的想法。对于许多测试,它使用ArgumentParser
具有自己error
方法的子类。