pytest:设置主要功能测试的命令行参数

Dot*_*tan 7 pytest argparse

我在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")
Run Code Online (Sandbox Code Playgroud)

hpa*_*ulj 7

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'])
Run Code Online (Sandbox Code Playgroud)

其中字符串列表复制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
Run Code Online (Sandbox Code Playgroud)

你可以测试

main(['foo', '-f','v'])
Run Code Online (Sandbox Code Playgroud)

unittesting文件argparse.py既使用了这种方法,也使用了您sys.argv直接修改的方法。

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

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

  • 您的解决方案如何进行 pytest 测试? (2认同)

Dot*_*tan 5

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

def test_main():
    sys.argv = ["some_name", "abc"]
    res = main()
Run Code Online (Sandbox Code Playgroud)

对于标志:

sys.argv.append("-f")
sys.argv.append("v")
Run Code Online (Sandbox Code Playgroud)


lea*_*eal 5

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

with unittest.mock.patch('sys.argv', ['--option1', 'inputFile']):
    main()
Run Code Online (Sandbox Code Playgroud)

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

我发现了一个不同的计算器后该解决方案在这里.