sys.argv的indexError和测试命令行参数

时间:2015-09-15 05:41:02

标签: python unit-testing sys

我正在编写各种单元测试用例:

import unittest
import program

class test(unittest.TestCase):
    a = 'acgt'
    b = 'c'
    sys.argv[1] = a
    sys.argv[2] = b
    text, patterns = program.parse()
    assertEqual(text, a)
    assertEqual(patterns, [b])

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

不幸的是,他们都返回IndexError索引超出范围。这是有道理的,因为命令行上没有传递任何内容。我如何填充sys.argv参数以便测试从sys.argv获取解析器的方法?

2 个答案:

答案 0 :(得分:1)

你可能得到的不仅仅是指数超出范围,更具体地说:

>>> import sys
>>> sys.argv[1] = 'foo'
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list assignment index out of range

dict不同,list不仅仅是您可以为项目分配任意索引,您有append个别项目或extend列表项目

另外,您对unittest.TestCase的使用是错误的。您必须定义测试方法,而不仅仅是在类声明下编写测试。看起来应该是这样的:

class MyTestCase(unittest.TestCase):

    def test_program_parse(self):
        a = 'acgt'
        b = 'c'
        sys.argv.append(a)
        sys.argv.append(b)
        text, patterns = program.parse()
        assertEqual(text, a)
        assertEqual(patterns, [b])

另外,你肯定不想像这样弄脏sys.argv,你想利用setUptearDown来清理数据,所以你可能有在你的测试用例类中有这样的东西:

    def setUp(self):
        self._original_argv = sys.argv

    def tearDown(self):
        sys.argv = self._original_argv

按照惯例,这两个方法应该是您的测试类中定义的前两个方法,以使您的测试用例的未来读者清楚易懂。

此外,正如您所看到的,您只需将新列表分配给sys.argv,例如您要测试的整个参数列表。

答案 1 :(得分:1)

您只需更改argv变量

即可
class MyTest(unittest.TestCase):
    def test(self):
        import sys
        sys.argv = ['0', '1', '2']
        program()


def program():
    import sys
    print(sys.argv[1])
    print(sys.argv[2])

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

但这不是推荐的方法。而是更改程序的签名,以便它接受一个列表,以便您可以轻松控制它的调用方式。

program(sys.argv)  # From command line
program(['param1', 'param2'])  # From Tests