python,unittest:有没有办法将命令行选项传递给应用程序

时间:2009-06-22 23:23:06

标签: python unit-testing

我有一个导入unittest并有一些TestCases的模块。我想要 接受一些命令行选项(例如下面的数据文件的名称), 但是当我尝试通过该选项时,我收到消息“选项-i not recognized”。是否可以让unittest +为应用程序提供选项(注意:我使用optparse来处理选项)?感谢。

$ python test_app_data.py -i data_1.txt

option -i not recognized

=====================

跟进:这是建议解决方案的实现:

import cfg_master  #has the optparse option-handling code

...

if __name__ == '__main__':    
    #add you app's options here...
    options_tpl = ('-i', '--in_dir', '-o', '--out_dir')
    del_lst = []
    for i,option in enumerate(sys.argv):
        if option in options_tpl:
            del_lst.append(i)
            del_lst.append(i+1)

    del_lst.reverse()
    for i in del_lst:
        del sys.argv[i]

    unittest.main()

5 个答案:

答案 0 :(得分:55)

基于Alex的答案,使用argparse实际上非常容易:

if __name__ == '__main__':
    parser = argparse.ArgumentParser()
    parser.add_argument('--input', default='My Input')
    parser.add_argument('filename', default='some_file.txt')
    parser.add_argument('unittest_args', nargs='*')

    args = parser.parse_args()
    # TODO: Go do something with args.input and args.filename

    # Now set the sys.argv to the unittest_args (leaving sys.argv[0] alone)
    sys.argv[1:] = args.unittest_args
    unittest.main()

我没有测试你可以传递给unittest的所有标志,看它们是否有效,但是传入测试名称确实有效,例如:

python test.py --input=foo data.txt MyTest

使用foodata.txt运行MyTest。

答案 1 :(得分:32)

在您未向我们展示的if __name__ == '__main__':部分中,在将控制权转移到optparse代码之前,您需要del sys.argv[1:]然后unittest,所以当你已经处理过它们时,后面的代码不会尝试再次解释你的命令行选项 。 (你自己的的一些选项也有点难以传递给unittest,尽管如果你有这么复杂的需求就可以做到。)

答案 2 :(得分:2)

我以为我会分享我的解决方案,在测试中添加一个--debug开关来控制记录器:

if __name__=='__main__':
     parser = argparse.ArgumentParser(description="Build a compilation script")
     parser.add_argument('--debug', help='Turn on debug messages', action='store_true', default=False)

     args = parser.parse_args()

     if args.debug:
         log_level = logging.DEBUG
     else:
         log_level = logging.INFO

     logging.basicConfig(level=log_level)
     sys.argv.pop()
     unittest.main()

然后我扩展unittest.TestCase以添加日志记录:

 class mcs_TestCase(unittest.TestCase, object):
     def __init__(self, *args, **kwargs):
         super(mcs_TestCase,self).__init__(*args,**kwargs)
         logging.basicConfig()
         self.logger = logging.getLogger(__name__)
         ...

现在我可以使用--debug在我的测试中打开和关闭消息,但在常规回归中会被忽略。

答案 3 :(得分:1)

对于小型独立应用程序,我使用初始的sentinel选项(-t)并在调用argparse.ArgumentParser()之前调用unittest.main()

if __name__ == "__main__":
    if len(sys.argv) > 1 and sys.argv[1] in ["-t", "--test"]:
        del(sys.argv[1])
        sys.exit(unittest.main()) # pass sys.argv[

    p = argparse.ArgumentParser()
    . . .

答案 4 :(得分:-6)

你不应该使用参数和选项来运行unittests,因为你可以通过这种方式在不同的,不太可预测的条件下运行它们。您应该弄清楚为什么需要使用不同的数据运行测试,并使测试套件足够完整,以覆盖所有数据集,而不是每次都以不同的方式运行。