python, unittest: есть ли способ передать приложению параметры командной строки

У меня есть модуль, который импортирует unittest и имеет несколько TestCases. Я хотел бы принять некоторые опции командной строки (например, ниже, имя файла данных), но когда я пытаюсь передать опцию, я получаю сообщение "опция -i не распознана". Возможно ли заставить 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()
Комментарии к вопросу (2)
Решение

В развитие ответа Алекса, это на самом деле довольно просто сделать, используя 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

Запускает MyTest с foo и data.txt.

Комментарии (6)

В секции if __name__ == '__main__':, которую вы'не показываете нам, вам'нужно optparse и затем del sys.argv[1:] перед передачей управления коду unittest, чтобы последний не пытался интерпретировать опции командной строки еще раз, когда вы'уже с ними разобрались. (Немного сложнее иметь некоторые собственные опции и также передавать некоторые из них в unittest, хотя это можно сделать, если у вас есть такие сложные потребности).

Комментарии (5)

Я думал, что я'д поделиться своим решением для добавления --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, но он игнорируется в обычных регрессий.

Комментарии (0)

Для небольших автономных приложений, я использую первоначальный вариант Сентинел (-T) и называть unittest.главная() перед вызовом argparse.ArgumentParser()

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()
    . . .
Комментарии (0)

Вы не должны принимать аргументы и опции для запуска нетестов, поскольку таким образом вы заставляете их работать в других, менее предсказуемых условиях. Вы должны выяснить, зачем вам нужно запускать тесты с разными данными, и сделать ваш набор тестов достаточно полным, чтобы охватить все наборы данных без необходимости каждый раз запускать их по-разному.

Комментарии (7)