根据我从另一篇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
尽管我能够构建一个有效的测试用例,但你真的应该提供足够的信息,我不需要猜测或挖掘。