我想在正在编写的某些代码中添加一些命令行参数,并且当我包含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
失败我什么都找不到。
帮助?
此行:
return parser.parse_args()
应该是
return parser.parse_args(args)
否则,parser.parse_args
默认为sys.argv[1:]
,这可能不是您想要的
也是要传递给的sys.argv
是来自pytest的调用中的值-您可能希望将其设置为对您的程序有意义的值
您在这里有〜两种选择
from unittest import mock
def test():
with mock.patch.object(sys, 'argv', ['yourprog', 'args', 'here']):
...
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'])