Argparse单元测试:取消帮助消息

时间:2013-09-06 06:55:50

标签: python unit-testing argparse

我正在为argparse实现编写测试用例。我打算测试'-h'功能。以下代码执行此操作。但它也输出脚本的用法。有没有办法压制它?

self.assertRaises(SystemExit, arg_parse_obj.parse_known_args, ['-h'])

另外,我们可以检查抛出的异常号码吗?例如,' - h'抛出 SystemExit:0 ,而无效或不充分的args抛出 SystemExit:2 。有没有办法检查数字代码?

3 个答案:

答案 0 :(得分:15)

在测试异常代码时,请使用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.stdoutsys.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个字符限制。

答案 1 :(得分:1)

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'])

补丁也可以作为装饰者。如果你有几个需要抑制argparse打印的实例,你可以将它作为装饰器来做,并避免使用一堆嵌套的语句。

答案 2 :(得分:0)

使用['-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方法。