Unittest with command-line arguments

时间:2015-09-14 16:10:18

标签: python unit-testing argparse

From what I understand from another SO post, to unittest a script that takes command line arguments through argparse, I should do something like the code below, giving sys.argv[0] as 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])

This returns the error:

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

I would like to understand what is going on here deeper. I understand

if __name__ == '__main__': main()

says that if this is being executed by the 'main', highest level, default interpreter, to just automatically run the 'main' method. I'm assuming

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

just happens to be the way you say this for running unittest scripts.

I understand when any script is run, it automatically has an argv object, a vector collecting all the items on the command line.

But I do not understand what unittest.main(sys.arg[0]) would do. What does 'unittest.main' do with arguments? How can I pre-set the values of sys.argv - doesn't it automatically reset every time you run a script? Furthermore, where does this object 'sys.argv' exist, if outside of any script? Finally, what is the correct way to implement tests of command-line arguments?

I am sorry if my questions are vague and misguided. I would like to understand all the components relevant here so I can actually understand what I am doing.

Thank you very much.

1 个答案:

答案 0 :(得分:0)

通过使用一对简单文件,我发现在调用者模块主体中修改sys.argv会影响导入模块看到的sys.argv

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

但是,如果您正在修改sys.argv块中的main,则不会在导入的块中显示。我们可以深入研究文档(和代码)以确切了解原因,但我认为仅仅确定哪些方法有效。

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

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

您还可以使用自己的字符串列表测试解析器,并认识到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

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