为主要功能测试设置命令行参数

Setting command line arguments for main function tests

我在 python 中有一个获取命令行参数的 main() 函数。 有没有办法为这个函数编写 pytest 测试并在代码中定义参数?

例如

def main():
    # argparse code
    args, other = arg_parser.parse_known_args()
    return args.first_arg


def test_main():
    res = main() # call with first_arg = "abc"
    assert(res == "abc")

到目前为止我找到的最好的解决方案是这个

def test_main():
    sys.argv = ["some_name", "abc"]
    res = main()

对于标志:

sys.argv.append("-f")
sys.argv.append("v")

parse_args 采用 argv 参数。文档在其示例中重复使用了它

parser = argparse.ArgumentParser()
parser.add_argument('--foo', action='store_true')
parser.add_argument('bar')
parser.parse_known_args(['--foo', '--badger', 'BAR', 'spam'])

其中字符串列表复制 sys.argv[1:] 它将从命令行获取。如果参数是 None(或省略),解析器使用 sys.argv[1:].

所以如果

def main(argv=None):
    # argparse code
    args, other = arg_parser.parse_known_args(argv)
    return args.first_arg

您可以使用

进行测试
main(['foo', '-f','v'])

argparse.pyunittesting 文件使用了这种方法,以及您直接修改 sys.argv 的方法。

https://docs.python.org/3/library/argparse.html#beyond-sys-argv

https://docs.python.org/3/library/argparse.html#partial-parsing

添加到以前的答案,而不是修改 sys.argv 使用可以掩盖和保护底层对象的上下文管理器更安全。一个例子是

with unittest.mock.patch('sys.argv', ['program_name', '--option1', 'inputFile']):
    main()

这仅适用于 python3。对于 python2,Mock 库可以解决问题。

我在不同的 Whosebug 上找到了这个解决方案 post here.