pytest和argparse:代码在使用中,但是测试失败

问题描述 投票:0回答:1

我想在正在编写的某些代码中添加一些命令行参数,并且当我包含argparse内容时,测试将失败。

这是基本类的简化版本:

import argparse
import sys


class PreProcessor:

    def parse_args(self, args):
        parser = argparse.ArgumentParser(description='Arguments for PreProcessor scripts.')
        parser.add_argument('-i', '--ignore-pid', help='If the script is already running, it will not re-run. This over-rides that.', action="store_true")
        parser.add_argument('-v', '--verbose', type=int, choices=[0,1,2,3], default=1, help='Be noisy when running [0 is completely silent, 3 is debug-level. defaults to 1].')
        return parser.parse_args()

    def __init__(
        self,
        code,
    ):
        if not code:
            raise ValueError("A code must be defined")
        self.code = code

        # These two lines
        self.args = self.parse_args(sys.argv)
        print(f"type: {type(self.args)}, data: {self.args}")

....这是它的测试文件:

import pytest
from .example import PreProcessor


def test_base_initialisation():
    foo = PreProcessor(code="foo")
    assert foo.code == "foo"

因此,我得到的错误是:

platform linux -- Python 3.6.9, pytest-3.3.2, py-1.5.2, pluggy-0.6.0 -- /usr/bin/python3
cachedir: .cache
rootdir: /home/kiz/development/FindingStudySpaces/preprocessors, inifile: pytest.ini
plugins: cov-2.5.1
collected 1 item                                                                                                                                                                                                                                                       
preprocessors/test_example.py::test_base_initialisation FAILED                     [100%]

 generated xml file: /home/kiz/development/FindingStudySpaces/preprocessors/pytest-results.xml 

----------- coverage: platform linux, python 3.6.9-final-0 -----------
Name                             Stmts   Miss  Cover
----------------------------------------------------
preprocessors/__init__.py            0      0   100%
preprocessors/example.py            14      2    86%
preprocessors/preprocessors.py     140    140     0%
----------------------------------------------------
TOTAL                              154    142     8%
Coverage HTML written to dir htmlcov

======================================== FAILURES ========================================
________________________________ test_base_initialisation ________________________________

self = ArgumentParser(prog='pytest-3', usage=None, description='Arguments for PreProcessor scripts.', formatter_class=<class 'argparse.HelpFormatter'>, conflict_handler='error', add_help=True)
action = _StoreAction(option_strings=['-v', '--verbose'], dest='verbose', nargs=None, const=None, default=1, type=<class 'int'>...es=[0, 1, 2, 3], help='Be noisy when running [0 is completely silent, 3 is debug-level. defaults to 1].', metavar=None)
arg_string = 'preprocessors/test_example.py'

    def _get_value(self, action, arg_string):
        type_func = self._registry_get('type', action.type, action.type)
        if not callable(type_func):
            msg = _('%r is not callable')
            raise ArgumentError(action, msg % type_func)

        # convert the value to the appropriate type
        try:
>           result = type_func(arg_string)
E           ValueError: invalid literal for int() with base 10: 'preprocessors/test_example.py'
         ... <snip loads of stuff> ...
                 # TypeErrors or ValueErrors also indicate errors
        except (TypeError, ValueError):
            name = getattr(action.type, '__name__', repr(action.type))
            args = {'type': name, 'value': arg_string}
            msg = _('invalid %(type)s value: %(value)r')
>           raise ArgumentError(action, msg % args)
E           argparse.ArgumentError: argument -v/--verbose: invalid int value: 'preprocessors/test_example.py'
         ... <snip loads more stuff> ...

我已经尝试通过sys.argv[1:]方法传递init-没有区别

如果我注释掉对argparse的调用(即,它说# These two lines的行,那么我就可以了。

我不是真的想向every测试方法添加模拟/补丁,不要在实时代码中放置一些子句以测试def parse_args(self, args)是否已由测试例程调用

....我的google-foo发现了一些有关测试参数传递的讨论(这很好)-但在此级别上argparse失败我什么都找不到。

帮助?

pytest argparse
1个回答
0
投票

此行:

        return parser.parse_args()

应该是

        return parser.parse_args(args)

否则,parser.parse_args默认为sys.argv[1:],这可能不是您想要的

也是要传递给的sys.argv是来自pytest的调用中的值-您可能希望将其设置为对您的程序有意义的值

您在这里有〜两种选择

  1. monkeypatch sys.argv:
from unittest import mock

def test():
    with mock.patch.object(sys, 'argv', ['yourprog', 'args', 'here']):
        ...
  1. 依赖关系注入您的参数并通过您的程序传递它们:
class C:
    def __init__(self, code, args=None):
        ...
        self.parse_args(args)

    def parse_args(self, args=None):
        ...
        return parser.parse_args(args)
    +
def test():
    thing = C(..., args=['args', 'here'])
© www.soinside.com 2019 - 2024. All rights reserved.