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

Posted

技术标签:

【中文标题】使用 unittest 检查“--help”标志输出【英文标题】:Using unittest to check "--help" flag output 【发布时间】:2020-05-02 11:11:26 【问题描述】:

我有一些使用 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 来检查帮助功能的输出。除非没有其他解决方案,否则我也不想更改实际代码。 帮助操作在打印到标准输出后内置了一个 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 对象为空,因此测试失败。

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

【问题讨论】:

单元测试argparse 很棘手。 test_argparse.py 使用 ArgumentParser 的子类,它重新定义了 error exit 方法,并重定向 stdoutstderr。您还可以使用 parser.format_help() 而不是完整的 ['-h'] 机制来测试 help 输出。 【参考方案1】:

我非常接近。 captured_output 实际上并不是空的——我只是没有正确访问内容。

在我的示例代码中将captured_output.get_value() 替换为captured_value,它可以完美运行。

【讨论】:

以上是关于使用 unittest 检查“--help”标志输出的主要内容,如果未能解决你的问题,请参考以下文章

g++ 在 -Os 处启用错误标志

使用 unittest 测试 argparse - 退出错误

unittest介绍

Linux150个常用命令

Python+appium+unittest UI自动化总结

unittest 单元测试