Argparse 单元测试:禁止显示帮助消息
Posted
技术标签:
【中文标题】Argparse 单元测试:禁止显示帮助消息【英文标题】:Argparse unit tests: Suppress the help message 【发布时间】:2013-09-10 04:41:43 【问题描述】:我正在为 argparse 实现编写测试用例。我打算测试'-h'功能。下面的代码做到了。但它也输出脚本的用法。有没有办法抑制它?
self.assertRaises(SystemExit, arg_parse_obj.parse_known_args, ['-h'])
另外,我们可以检查抛出的异常号吗?例如 '-h' 抛出 SystemExit: 0,而无效或不足的 args 抛出 SystemExit: 2。有没有办法检查数字代码?
【问题讨论】:
【参考方案1】:测试异常代码时,使用self.assertRaises()
as a context manager;这使您可以访问引发的异常,让您测试.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 个字符限制。
【讨论】:
哎呀,我认为with
将允许连续括号,但它没有,所以你不能做像with (really_long_expression as a, <NEWLINE>really_really_long_expression as b): suite
这样的事情。
我讨厌使用反斜杠来继续。我希望将来他们会允许括号。我能看到的唯一问题是允许他们使用语法with (<expr>, <expr>, ...):
(不使用as
)将是模棱两可的,因为它可能意味着使用嵌套的上下文管理器,或者将元组本身用作上下文管理器(它不没有意义...)。
我将此代码复制并粘贴到3.5
和stdout
是空的,而帮助消息打印在stderr
中
@raphael:默认情况下,帮助转到标准输出(请参阅print_help()
function)。如果出现错误,则使用print_usage()
和given stdout
as the output to write to。
@MartijnPieters 啊,我的 b。我以您的代码为基础,但尝试测试错误并错过了区别【参考方案2】:
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 语句。
【讨论】:
【参考方案3】:使用['-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
) 还提供了有关如何测试事物的想法。对于许多测试,它使用具有自己的error
方法的ArgumentParser
子类。
【讨论】:
以上是关于Argparse 单元测试:禁止显示帮助消息的主要内容,如果未能解决你的问题,请参考以下文章