У меня есть модуль, который импортирует 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()
В развитие ответа Алекса, это на самом деле довольно просто сделать, используя 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
.
В секции if __name__ == '__main__':
, которую вы'не показываете нам, вам'нужно optparse
и затем del sys.argv[1:]
перед передачей управления коду unittest
, чтобы последний не пытался интерпретировать опции командной строки еще раз, когда вы'уже с ними разобрались. (Немного сложнее иметь некоторые собственные опции и также передавать некоторые из них в unittest
, хотя это можно сделать, если у вас есть такие сложные потребности).
Я думал, что я'д поделиться своим решением для добавления --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, но он игнорируется в обычных регрессий.
Для небольших автономных приложений, я использую первоначальный вариант Сентинел (-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()
. . .
Вы не должны принимать аргументы и опции для запуска нетестов, поскольку таким образом вы заставляете их работать в других, менее предсказуемых условиях. Вы должны выяснить, зачем вам нужно запускать тесты с разными данными, и сделать ваш набор тестов достаточно полным, чтобы охватить все наборы данных без необходимости каждый раз запускать их по-разному.