使用unittest检查“ --help”标志输出

时间:2020-01-15 16:21:36

标签: python unit-testing argparse stringio

我有一些使用argparse解析命令行选项的代码。

例如:

# mycode.py

import argparse

def parse_args():
    parser = argparse.ArgumentParser('my code')
    # list of arguments
    # ...
    # ...
    return vars(parser.parse_args())

if __name__ == "__main__":
    parse_args()

我想使用unittest来检查帮助功能的输出。除非没有其他解决方案,否则我也不想更改实际代码。 打印到标准输出后,help操作中内置了一个SystemExit调用,因此我不得不尝试在单元测试中将其捕获。

这是我的单元测试代码,其中包含以下步骤:

1)设置sys.argv列表以包含-h标志。

2)在上下文管理器中包装函数调用,以防止将SystemExit视为错误。

3)暂时将sys.stdout切换到io.StringIO对象,这样我就可以检查它而不用打印到屏幕上。

4)在try...finally块中调用该函数,以使SystemExit不会致命。

5)将sys.stdout切换回真实的stdout

6)打开一个我之前保存过帮助文本的文件(通过在终端中输入python mycode.py -h > help_out.txt)以验证其与从StringIO捕获的输出相同。

import unittest
import mycode
import sys
import io

class TestParams(unittest.TestCase):

    def setUp(self):
        pass

    def test_help(self):
        args = ["-h"]
        sys.argv[1:] = args
        with self.assertRaises(SystemExit):
            captured_output = io.StringIO()
            sys.stdout = captured_output
            try:
                mycode.parse_args()
            finally:
                sys.stdout = sys.__stdout__
                with open("help_out.txt", "r") as f:
                    help_text = f.read()
                    self.assertEqual(captured_output, help_text)

    def tearDown(self):
        pass

此代码有效,但是captured_output StringIO对象为空,因此测试失败。

我正在寻找有关捕获的输出和/或替代解决方案出了什么问题的解释。

1 个答案:

答案 0 :(得分:0)

我非常亲密。 captured_output实际上不是空的-我只是没有正确访问内容。

在我的示例代码中用captured_output.get_value()代替captured_value,它可以正常工作。