Как вы пишете тесты для части argparse модуля python?

У меня есть модуль Python, который использует библиотеку argparse. Как написать тесты для этого раздела базы кода?

6 Solutions collect form web for “Как вы пишете тесты для части argparse модуля python?”

Вы должны реорганизовать свой код и переместить синтаксический анализ на функцию:

def parse_args(args): parser = argparse.ArgumentParser(...) parser.add_argument... # ...Create your parser as you like... return parser.parse_args(args) 

Затем в вашей main функции вы должны просто вызвать его с помощью:

 parser = parse_args(sys.argv[1:]) 

(где первый элемент sys.argv который представляет имя сценария, удаляется, чтобы не отправлять его в качестве дополнительного переключателя во время операции CLI.)

В ваших тестах вы можете вызвать функцию парсера с любым списком аргументов, которые вы хотите проверить с помощью:

 def test_parser(self): parser = parse_args(['-l', '-m']) self.assertTrue(parser.long) # ...and so on. 

Таким образом, вы никогда не должны будете выполнять код своего приложения, просто чтобы проверить парсер.

Если вам нужно изменить и / или добавить параметры в свой синтаксический анализатор позже в приложении, создайте фабричный метод:

 def create_parser(): parser = argparse.ArgumentParser(...) parser.add_argument... # ...Create your parser as you like... return parser 

Вы можете позже манипулировать им, если хотите, и тест может выглядеть так:

 class ParserTest(unittest.TestCase): def setUp(self): self.parser = create_parser() def test_something(self): parsed = self.parser.parse_args(['--something', 'test']) self.assertEqual(parsed.something, 'test') 

«часть argparse» немного туманна, поэтому этот ответ фокусируется на одной части: методе parse_args . Это метод, который взаимодействует с вашей командной строкой и получает все переданные значения. В принципе, вы можете издеваться над тем, что возвращает parse_args так что ему не нужно фактически получать значения из командной строки.

 import argparse import mock @mock.patch('argparse.ArgumentParser.parse_args', return_value=argparse.Namespace(kwarg1=value, kwarg2=value)) def test_command(mock_args): pass 

Вы должны включить все аргументы вашего метода команды в Namespace даже если они не переданы. Дайте этим аргументам значение None . (см. документы ). Этот стиль полезен для быстрого выполнения тестирования для случаев, когда разные значения передаются для каждого аргумента метода. Если вы решите издеваться над самим Namespace для полной неопределенности argparse в своих тестах, убедитесь, что он ведет себя аналогично действительному классу Namespace .

  1. sys.argv.append() свой список arg, используя sys.argv.append() а затем вызовите parse() , проверьте результаты и повторите.
  2. Вызовите из файла batch / bash ваши флагов и флаг args dump.
  3. Поместите весь свой анализ аргументов в отдельный файл и в if __name__ == "__main__": выведите синтаксический анализ и дамп / оцените результаты, затем проверьте это из файла batch / bash.

Простой способ тестирования парсера:

 parser = ... parser.add_argument('-a',type=int) ... argv = '-a 1 foo'.split() # or ['-a','1','foo'] args = parser.parse_args(argv) assert(args.a == 1) ... 

Другой способ – изменить sys.argv и вызвать args = parser.parse_args()

Существует множество примеров тестирования argparse в lib/test/test_argparse.py

Сделайте свою функцию main() принять argv как аргумент, а не позволить ему читать из sys.argv поскольку он будет по умолчанию :

 # mymodule.py import argparse import sys def main(args): parser = argparse.ArgumentParser() parser.add_argument('-a') process(**vars(parser.parse_args(args))) return 0 def process(a=None): pass if __name__ == "__main__": sys.exit(main(sys.argv[1:])) 

Тогда вы можете нормально протестировать.

 import mock from mymodule import main @mock.patch('mymodule.process') def test_main(process): main([]) process.assert_call_once_with(a=None) @mock.patch('foo.process') def test_main_a(process): main(['-a', '1']) process.assert_call_once_with(a='1') 

Я обнаружил, что самый простой способ, по крайней мере для меня, состоял в том, чтобы просто проверить sys.argv [0], чтобы посмотреть, запущен ли python как python -m unittest и не разбирать что-либо, если это так.

 import sys import argparse parser = argparse.ArgumentParser() parser.add_argument('--outdir', help='Directory to output to', \ default='out') parser.add_argument('--file', help='Input file', \ default='section') parser.add_argument('--word', help='Word to look up') if sys.argv[0] == 'python -m unittest': args = parser.parse_args([]) else: args = parser.parse_args() по import sys import argparse parser = argparse.ArgumentParser() parser.add_argument('--outdir', help='Directory to output to', \ default='out') parser.add_argument('--file', help='Input file', \ default='section') parser.add_argument('--word', help='Word to look up') if sys.argv[0] == 'python -m unittest': args = parser.parse_args([]) else: args = parser.parse_args() по import sys import argparse parser = argparse.ArgumentParser() parser.add_argument('--outdir', help='Directory to output to', \ default='out') parser.add_argument('--file', help='Input file', \ default='section') parser.add_argument('--word', help='Word to look up') if sys.argv[0] == 'python -m unittest': args = parser.parse_args([]) else: args = parser.parse_args() 
  • Длинное определение объекта внутри модульного теста Python
  • Почему утверждения в unittest используют TestCase.assertEqual, а не ключевое слово assert?
  • Попытка реализовать python TestSuite
  • Какие числа вы можете передать как многословие при запуске Python Unit Test Suites?
  • Тестирование представлений Django, требующих входа в систему с помощью RequestFactory
  • Как модульный тестовый код, который выполняет задачи сельдерея?
  • Каков правильный способ сообщить об ошибке в унитате Python в методе setUp?
  • Изменение глобальных переменных в системе unitest Python
  •  
    Interesting Posts for Van-Lav

    Не удалось создать вторую python python dataframe

    Django manytomany сигналы?

    Вычисление с полным разрешением с помощью matplotlib.pyplot, imshow () и savefig ()?

    Как обернуть функцию c ++, которая принимает указатель на функцию в python с помощью SWIG

    Обновление нескольких терминалов Python

    Как шифровать все возможные строки в определенном наборе символов python?

    Python изменяет размер анимированного gif с PIL

    Python: список слияния с диапазоном

    Что вызывает эту ошибку при попытке установить virtualenv? IOError: Разрешение отклонено: '/Library/Python/2.7/site-packages/virtualenv.py'

    Как извлечь поля PDF из заполненной формы в Python?

    Вычисление локальных средств в массиве 1D numpy

    Приложение twilio App to App не работает

    Является ли pythonic использование интерфейсов / абстрактных базовых классов?

    Numpy выбирает определенный индекс столбца для каждой строки, используя список индексов

    Существует ли Perl эквивалент Python `if __name__ == '__main __'`?

    Python - лучший язык программирования в мире.