У меня есть некоторый код, который анализирует параметры командной строки с использованием argparse.
Например:
# mycode.py
import argparse
def parse_args():
parser = argparse.ArgumentParser('my code')
# list of arguments
# ...
# ...
return vars(parser.parse_args())
if __name__ == "__main__":
parse_args()
Я хотел бы использовать unittest для проверки выходных данных функции справки. Я также не хочу менять реальный код, если нет другого решения. У действия помощи есть встроенный вызов SystemExit
после печати в stdout, поэтому мне пришлось попытаться перехватить его в unittest.
Вот мой код unittest со следующими шагами:
1) Установите список sys.argv
, включающий флаг -h
.
2) Оберните вызов функции в диспетчере контекста, чтобы предотвратить просмотр SystemExit
как ошибки.
3) Временно переключите sys.stdout
на объект io.StringIO
, чтобы я мог осмотреть его без печати на экране.
4) Вызвать функцию в блоке try...finally
, чтобы SystemExit
не смертельно.
5) Переключить sys.stdout
обратно на реальный stdout
.
6) Открыть файл, в который я ранее сохранил текст справки (введя * 1030) * в терминале), чтобы убедиться, что он совпадает с записанным выводом из StringIO
.
import unittest
import mycode
import sys
import io
class TestParams(unittest.TestCase):
def setUp(self):
pass
def test_help(self):
args = ["-h"]
sys.argv[1:] = args
with self.assertRaises(SystemExit):
captured_output = io.StringIO()
sys.stdout = captured_output
try:
mycode.parse_args()
finally:
sys.stdout = sys.__stdout__
with open("help_out.txt", "r") as f:
help_text = f.read()
self.assertEqual(captured_output, help_text)
def tearDown(self):
pass
Этот код работает, но объект captured_output
StringIO
пуст, поэтому тест не пройден .
Я ищу объяснение того, что не так с захваченным выводом и / или альтернативным решением. Тион.