带有命令行参数的Unittest



根据我从另一篇SO文章中了解到的情况,为了对通过argparse获取命令行参数的脚本进行单元测试,我应该执行类似以下代码的操作,将sys.argv[0]作为arg。

import unittest
import match_loc
class test_method_main(unittest.TestCase):
    loc = match_loc.main()
    self.assertEqual(loc, [4])

if __name__ == '__main__':
    sys.argv[1] = 'aaaac'
    sys.argv[2] = 'ac'
    unittest.main(sys.argv[0])

这会返回错误:

usage: test_match_loc.py [-h] text patterns [patterns ...]
test_match_loc.py: error: the following arguments are required: text, patterns

我想更深入地了解这里发生了什么。我了解

if __name__ == '__main__': main()

表示如果这是由"main"(最高级别的默认解释器(执行的,则只自动运行"main"方法。我假设

if __name__ == '__main__': unittest.main()

这恰好是运行单元测试脚本的方式。

我知道,当运行任何脚本时,它都会自动拥有一个argv对象,一个收集命令行上所有项目的向量。

但我不明白unittest.main(sys.arg[0])会做什么。"unittest.main"对参数有什么作用?我如何预设sys.argv的值?它不是每次运行脚本时都会自动重置吗?此外,如果在任何脚本之外,这个对象'sys.argv'存在于哪里?最后,实现命令行参数测试的正确方法是什么?

如果我的问题含糊其辞,被误导了,我很抱歉。我想了解这里的所有相关组件,这样我才能真正了解我在做什么。

非常感谢。

只要玩一对简单的文件,我就会发现在调用方模块的主体中修改sys.argv会影响导入模块看到的sys.argv

import sys
sys.argv[1] = 'aaaac'
sys.argv[2] = 'ac'
class test_method_main(unittest.TestCase):
   ...

但是,在main块中修改sys.argv不会显示在导入的块中。我们可以深入研究文档(和代码(来了解确切的原因,但我认为只确定什么是有效的就足够了。

以下是我从您之前关于导入模块的问题中重建的内容-带有一些诊断打印

import argparse
import sys
def main():
    print(sys.argv)
    parser = argparse.ArgumentParser(
            description='Takes a series of patterns as fasta files'
            ' or strings and a text as fasta file or string and'
            ' returns the match locations by constructing a trie.')
    parser.add_argument('text')
    parser.add_argument('patterns', nargs='+')
    args = parser.parse_args()
    print(args)
    return 1

您还可以使用自己的字符串列表测试解析器,识别出如果参数丢失或None:,parse_args将使用sys.argv[1:]

def main(argv=None):
    print(argv)
    ...
    args = parser.parse_args(argv)
    print(args)
    return 1
loc = match_loc.main(['abc','ab'])  # and in the caller

尽管我能够构建一个有效的测试用例,但你真的应该提供足够的信息,我不需要猜测或挖掘。

最新更新