检查 argparse.ArgumentTypeError
Check argparse.ArgumentTypeError
我想使用 pytest
检查 argparse.ArgumentTypeError
异常是否因参数不正确而引发:
import argparse
import os
import pytest
def main(argsIn):
def configFile_validation(configFile):
if not os.path.exists(configFile):
msg = 'Configuration file "{}" not found!'.format(configFile)
raise argparse.ArgumentTypeError(msg)
return configFile
parser = argparse.ArgumentParser()
parser.add_argument('-c', '--configFile', help='Path to configuration file', dest='configFile', required=True, type=configFile_validation)
args = parser.parse_args(argsIn)
def test_non_existing_config_file():
with pytest.raises(argparse.ArgumentTypeError):
main(['--configFile', 'non_existing_config_file.json'])
然而,运行 pytest
表示 During handling of the above exception, another exception occurred:
因此测试失败。我做错了什么?
问题是,如果参数的类型转换器引发异常 ArgumentTypeError
agrparse
exits,错误代码为 2,退出意味着引发内置异常 SystemExit
。因此,您必须捕获该异常并验证原始异常的类型是否正确:
def test_non_existing_config_file():
try:
main(['--configFile', 'non_existing_config_file.json'])
except SystemExit as e:
assert isinstance(e.__context__, argparse.ArgumentError)
else:
raise ValueError("Exception not raised")
这是 test_argparse.py
文件中的 ArgumentTypeError
测试(在开发存储库中找到)
ErrorRaisingAgumentParser
是定义在文件开头的子类,重新定义了parser.error
方法,所以不退出,把错误信息放在stderr
上。那部分有点复杂。
由于我在评论中描述的重定向,它无法直接测试 ArgumentTypeError
。相反,它必须测试其消息。
# =======================
# ArgumentTypeError tests
# =======================
class TestArgumentTypeError(TestCase):
def test_argument_type_error(self):
def spam(string):
raise argparse.ArgumentTypeError('spam!')
parser = ErrorRaisingArgumentParser(prog='PROG', add_help=False)
parser.add_argument('x', type=spam)
with self.assertRaises(ArgumentParserError) as cm:
parser.parse_args(['XXX'])
self.assertEqual('usage: PROG x\nPROG: error: argument x: spam!\n',
cm.exception.stderr)
使用 pytest
您可以执行以下操作以检查是否引发了 argparse.ArugmentError
。此外,您可以检查错误消息。
with pytest.raises(SystemExit) as e:
main(['--configFile', 'non_existing_config_file.json'])
assert isinstance(e.value.__context__, argparse.ArgumentError)
assert 'expected err msg' in e.value.__context__.message
我想使用 pytest
检查 argparse.ArgumentTypeError
异常是否因参数不正确而引发:
import argparse
import os
import pytest
def main(argsIn):
def configFile_validation(configFile):
if not os.path.exists(configFile):
msg = 'Configuration file "{}" not found!'.format(configFile)
raise argparse.ArgumentTypeError(msg)
return configFile
parser = argparse.ArgumentParser()
parser.add_argument('-c', '--configFile', help='Path to configuration file', dest='configFile', required=True, type=configFile_validation)
args = parser.parse_args(argsIn)
def test_non_existing_config_file():
with pytest.raises(argparse.ArgumentTypeError):
main(['--configFile', 'non_existing_config_file.json'])
然而,运行 pytest
表示 During handling of the above exception, another exception occurred:
因此测试失败。我做错了什么?
问题是,如果参数的类型转换器引发异常 ArgumentTypeError
agrparse
exits,错误代码为 2,退出意味着引发内置异常 SystemExit
。因此,您必须捕获该异常并验证原始异常的类型是否正确:
def test_non_existing_config_file():
try:
main(['--configFile', 'non_existing_config_file.json'])
except SystemExit as e:
assert isinstance(e.__context__, argparse.ArgumentError)
else:
raise ValueError("Exception not raised")
这是 test_argparse.py
文件中的 ArgumentTypeError
测试(在开发存储库中找到)
ErrorRaisingAgumentParser
是定义在文件开头的子类,重新定义了parser.error
方法,所以不退出,把错误信息放在stderr
上。那部分有点复杂。
由于我在评论中描述的重定向,它无法直接测试 ArgumentTypeError
。相反,它必须测试其消息。
# =======================
# ArgumentTypeError tests
# =======================
class TestArgumentTypeError(TestCase):
def test_argument_type_error(self):
def spam(string):
raise argparse.ArgumentTypeError('spam!')
parser = ErrorRaisingArgumentParser(prog='PROG', add_help=False)
parser.add_argument('x', type=spam)
with self.assertRaises(ArgumentParserError) as cm:
parser.parse_args(['XXX'])
self.assertEqual('usage: PROG x\nPROG: error: argument x: spam!\n',
cm.exception.stderr)
使用 pytest
您可以执行以下操作以检查是否引发了 argparse.ArugmentError
。此外,您可以检查错误消息。
with pytest.raises(SystemExit) as e:
main(['--configFile', 'non_existing_config_file.json'])
assert isinstance(e.value.__context__, argparse.ArgumentError)
assert 'expected err msg' in e.value.__context__.message