我有一个使用argparse库的Python模块。如何为这部分代码库编写测试?
当前回答
你应该重构你的代码,并将解析移动到一个函数:
def parse_args(args):
parser = argparse.ArgumentParser(...)
parser.add_argument...
# ...Create your parser as you like...
return parser.parse_args(args)
然后在你的main函数中,你只需调用它:
parser = parse_args(sys.argv[1:])
(其中sys. js的第一个元素。表示脚本名称的argv被删除,以便在CLI操作期间不将其作为额外的交换机发送。)
在你的测试中,你可以用你想要测试的参数列表来调用解析器函数:
def test_parser(self):
parser = parse_args(['-l', '-m'])
self.assertTrue(parser.long)
# ...and so on.
这样,您就不必为了测试解析器而执行应用程序的代码。
如果你以后需要在你的应用程序中更改和/或添加选项到你的解析器中,那么创建一个工厂方法:
def create_parser():
parser = argparse.ArgumentParser(...)
parser.add_argument...
# ...Create your parser as you like...
return parser
如果你愿意,你可以稍后对它进行操作,测试可以是这样的:
class ParserTest(unittest.TestCase):
def setUp(self):
self.parser = create_parser()
def test_something(self):
parsed = self.parser.parse_args(['--something', 'test'])
self.assertEqual(parsed.something, 'test')
其他回答
通过使用sys.argv.append()填充你的参数列表,然后调用 Parse(),检查结果并重复。 使用标记和dump args标记从批处理/bash文件调用。 将所有参数解析放在一个单独的文件中,并在if __name__ == "__main__":调用解析并转储/评估结果,然后从批处理/bash文件中测试。
你应该重构你的代码,并将解析移动到一个函数:
def parse_args(args):
parser = argparse.ArgumentParser(...)
parser.add_argument...
# ...Create your parser as you like...
return parser.parse_args(args)
然后在你的main函数中,你只需调用它:
parser = parse_args(sys.argv[1:])
(其中sys. js的第一个元素。表示脚本名称的argv被删除,以便在CLI操作期间不将其作为额外的交换机发送。)
在你的测试中,你可以用你想要测试的参数列表来调用解析器函数:
def test_parser(self):
parser = parse_args(['-l', '-m'])
self.assertTrue(parser.long)
# ...and so on.
这样,您就不必为了测试解析器而执行应用程序的代码。
如果你以后需要在你的应用程序中更改和/或添加选项到你的解析器中,那么创建一个工厂方法:
def create_parser():
parser = argparse.ArgumentParser(...)
parser.add_argument...
# ...Create your parser as you like...
return parser
如果你愿意,你可以稍后对它进行操作,测试可以是这样的:
class ParserTest(unittest.TestCase):
def setUp(self):
self.parser = create_parser()
def test_something(self):
parsed = self.parser.parse_args(['--something', 'test'])
self.assertEqual(parsed.something, 'test')
我不想修改原来的服务脚本,所以我只是模拟出了系统。argparse中的Argv部分。
from unittest.mock import patch
with patch('argparse._sys.argv', ['python', 'serve.py']):
... # your test code here
如果argparse实现发生变化,这就会中断,但对于快速测试脚本来说已经足够了。在测试脚本中,敏感性要比特异性重要得多。
parse_args抛出SystemExit并输出到stderr,你可以捕获这两个:
import contextlib
import io
import sys
@contextlib.contextmanager
def captured_output():
new_out, new_err = io.StringIO(), io.StringIO()
old_out, old_err = sys.stdout, sys.stderr
try:
sys.stdout, sys.stderr = new_out, new_err
yield sys.stdout, sys.stderr
finally:
sys.stdout, sys.stderr = old_out, old_err
def validate_args(args):
with captured_output() as (out, err):
try:
parser.parse_args(args)
return True
except SystemExit as e:
return False
检查stderr(使用err.seek(0);Err.read()但通常不需要这种粒度。
现在你可以使用assertTrue或任何你喜欢的测试:
assertTrue(validate_args(["-l", "-m"]))
或者你可能想捕获并重新抛出一个不同的错误(而不是SystemExit):
def validate_args(args):
with captured_output() as (out, err):
try:
return parser.parse_args(args)
except SystemExit as e:
err.seek(0)
raise argparse.ArgumentError(err.read())
测试解析器的一个简单方法是:
parser = ...
parser.add_argument('-a',type=int)
...
argv = '-a 1 foo'.split() # or ['-a','1','foo']
args = parser.parse_args(argv)
assert(args.a == 1)
...
另一种方法是修改sys. conf。然后调用args = parser.parse_args()
在lib/test/test_argparse.py中有很多测试argparse的例子
推荐文章
- 如何为python模块的argparse部分编写测试?
- 在python中是否有用于均方根误差(RMSE)的库函数?
- 如何从matplotlib (pyplot。Figure vs matplotlib。figure) (frameon=False matplotlib中有问题)
- django test app error -在创建测试数据库时出现错误:创建数据库的权限被拒绝
- 识别使用pip安装的python包的依赖关系
- 从字符串变量导入模块
- 如何删除Python中的前导空白?
- python中的assertEquals和assertEqual
- 如何保持Python打印不添加换行符或空格?
- 为什么Python的无穷散列中有π的数字?
- Python 3.7数据类中的类继承
- 如何在PyTorch中初始化权重?
- 计数唯一的值在一列熊猫数据框架像在Qlik?
- 使用Pandas将列转换为行
- 从matplotlib中的颜色映射中获取单个颜色