使用 Pytest 框架进行 Argparse 测试

Posted

技术标签:

【中文标题】使用 Pytest 框架进行 Argparse 测试【英文标题】:Argparse testing with Pytest framework 【发布时间】:2019-12-17 08:43:08 【问题描述】:

我正在尝试为我的 argparse 模块编写单元测试用例。但是,测试没有按预期工作。我的代码如下:

import argparse

def create_parser():
    PARSER = argparse.ArgumentParser(prog='traffic_problem_one', \
   orbit2_traffic_speed', description='Geek Trust traffic problem', \
    allow_abbrev=False)

    PARSER.add_argument('Climate', metavar='--climate', action='store', type=str, help='Climate condition')
    PARSER.add_argument('Orbit1', metavar='--orbit1', action='store', type=int, help='Orbit 1 traffic speed')
    PARSER.add_argument('Orbit2', metavar='--orbit2', action='store', type=int, help='Orbit 2 traffic speed')

    return PARSER

PARSER = create_parser()
ARGS = PARSER.parse_args()

input = [ARGS.Climate, ARGS.Orbit1, ARGS.Orbit2]

对应的测试文件如下:

import sys
import os

sys.path.append(os.path.dirname(__file__)+"/../")
from src.main import *
from unittest import TestCase

class CommandLineTestCase(TestCase):
    """
    Base TestCase class, sets up a CLI parser
    """
    @classmethod
    def setUpClass(cls):
        parser = create_parser()
        cls.parser = parser

当我使用命令pytest test_main.py 执行时,会显示以下错误:

latform darwin -- Python 3.7.0, pytest-3.8.0, py-1.6.0, pluggy-0.7.1 -- /Users/xyx/anaconda3/bin/python
cachedir: .pytest_cache
rootdir: /Users/xyz/Xyz/gitDownloads/geekttrustproblems, inifile:
plugins: remotedata-0.3.0, openfiles-0.3.0, doctestplus-0.1.3, arraydiff-0.2
collected 0 items / 1 errors                                                                                                                                                      

===================================================================================== ERRORS ======================================================================================
_______________________________________________________________________ ERROR collecting test/test_main.py ________________________________________________________________________
test/test_main.py:5: in <module>
    from src.main import *
src/main.py:29: in <module>
    ARGS = PARSER.parse_args()
../../../anaconda3/lib/python3.7/argparse.py:1749: in parse_args
    args, argv = self.parse_known_args(args, namespace)
../../../anaconda3/lib/python3.7/argparse.py:1781: in parse_known_args
    namespace, args = self._parse_known_args(args, namespace)
../../../anaconda3/lib/python3.7/argparse.py:2016: in _parse_known_args
    ', '.join(required_actions))
../../../anaconda3/lib/python3.7/argparse.py:2501: in error
    self.exit(2, _('%(prog)s: error: %(message)s\n') % args)
../../../anaconda3/lib/python3.7/argparse.py:2488: in exit
    _sys.exit(status)
E   SystemExit: 2
--------------------------------------------------------------------------------- Captured stderr ---------------------------------------------------------------------------------
usage: traffic_problem_one [-h] --climate --orbit1 --orbit2
traffic_problem_one: error: the following arguments are required: --orbit1, --orbit2
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
============================================================================= 1 error in 0.29 seconds =============================================================================

【问题讨论】:

parse_args() 解析来自命令行的sys.argv 列表。但是在调用测试仪时,命令行值(如果有)将由测试仪使用,而不是您的脚本。像这样在命令行解析器上运行单元测试并非易事。你真的需要在这部分代码上做pytest吗? 作为代码覆盖率的一部分,确实需要对其进行测试 但是你要测试吗?只是parser 的创建?解析特定的输入?解析来自测试人员的任意输入? @hpaulj 您可以轻松模拟 sys.argv 进行测试 是的,有办法传递修改后的sys.argv 或替代解析器。这已在之前的 SO 中介绍过。但我不确定 OP 是否足以解决这些问题。 【参考方案1】:

您的参数解析是在您的模块导入时发生的。原因是您在任何函数之外的***范围内调用PARSER.parse_args()。为防止这种情况并允许您的代码正确导入,请添加__name__ == "__main__" 检查:

if __name__ == "__main__":
    PARSER = create_parser()
    ARGS = PARSER.parse_args()

    input = [ARGS.Climate, ARGS.Orbit1, ARGS.Orbit2]

【讨论】:

现在会尝试同样的方法 谢谢,它成功了。我已经把相同的外部***范围,因为我需要在不同的程序中的属性 INPUT。如果你能帮助我,那就太好了 从另一个程序调用main.py时如何使用输入。

以上是关于使用 Pytest 框架进行 Argparse 测试的主要内容,如果未能解决你的问题,请参考以下文章

pytest简介

如何在使用 argparse 的文件上使用指定的测试目录运行 pytest?

pytest argparse 测试用例不起作用

Pytest with argparse:如何测试用户被提示确认?

Pytest测试用例介绍

argparse 解析器:覆盖选项