У меня есть модуль Python, который использует библиотеку argparse. Как мне написать тесты для этого раздела базы кода?
python
unit-testing
argparse
pydanny
источник
источник
foo()
вызывается функция ». Насмешкаsys.argv
- это ответ, если это так. Взгляните на пакет Python cli-test-helpers . См. Также stackoverflow.com/a/58594599/202834Ответы:
Вы должны реорганизовать свой код и перенести анализ в функцию:
Тогда в вашей
main
функции вы должны просто вызвать его с помощью:(где первый элемент
sys.argv
, представляющий имя сценария, удален, чтобы не отправлять его в качестве дополнительного переключателя во время работы интерфейса командной строки.)В ваших тестах вы можете затем вызвать функцию синтаксического анализатора с любым списком аргументов, с которым вы хотите протестировать ее:
Таким образом, вам никогда не придется выполнять код вашего приложения только для проверки парсера.
Если вам нужно изменить и / или добавить параметры для вашего парсера позже в вашем приложении, то создайте фабричный метод:
Позже вы можете манипулировать им, если хотите, и тест может выглядеть так:
источник
2
...argparse
не очень подходит для тестирования, так как оно печатается напрямуюsys.stderr
...«argparse part» немного расплывчатый, поэтому этот ответ фокусируется на одной части:
parse_args
методе. Это метод, который взаимодействует с вашей командной строкой и получает все переданные значения. По сути, вы можете смоделироватьparse_args
возвращаемое значение, чтобы на самом деле не нужно было получать значения из командной строки.mock
Пакет может быть установлен через пип для питона версии 2,6-3,2. Это часть стандартной библиотеки,unittest.mock
начиная с версии 3.3.Вы должны включить все аргументы вашего командного метода,
Namespace
даже если они не переданы. Дайте этим аргументам значениеNone
. (см. документы ) Этот стиль полезен для быстрого выполнения тестирования в случаях, когда для каждого аргумента метода передаются разные значения. Если вы решили издеватьсяNamespace
полным отсутствием уверенности в ваших тестах, убедитесь, что он ведет себя аналогично фактическомуNamespace
классу.Ниже приведен пример использования первого фрагмента из библиотеки argparse.
источник
argparse
и от егоNamespace
класса. Вы должны издеватьсяNamespace
.from unittest import mock
теперь правильный метод импорта - по крайней мере, для python3Namespace
класса здесь именно то, что я искал. Несмотря на то, что тест все еще полагаетсяargparse
, он не зависит от конкретной реализацииargparse
тестируемого кода, что важно для моих модульных тестов. Кроме того, это простое в использованииpytest
«sparametrize()
способа быстро проверить различные комбинации аргументов с шаблонным макетом , который включает в себяreturn_value=argparse.Namespace(accumulate=accumulate, integers=integers)
.Сделайте так, чтобы ваша
main()
функция воспринималасьargv
как аргумент, а не позволяла ей читать,sys.argv
как это будет по умолчанию :Тогда вы можете проверить нормально.
источник
sys.argv.append()
а затем позвонитеparse()
, проверьте результаты и повторите.if __name__ == "__main__":
синтаксический анализ вызова и дампа / оценки результатов, а затем проверить это из пакетного / bash-файла.источник
Я не хотел изменять оригинальный сценарий обслуживания, поэтому я просто
sys.argv
вырезал часть в argparse.Это ломается, если изменяется реализация argparse, но этого достаточно для сценария быстрого тестирования. В любом случае, чувствительность гораздо важнее специфики тестовых сценариев.
источник
Простой способ тестирования парсера:
Другой способ изменить
sys.argv
и вызватьargs = parser.parse_args()
Есть много примеров тестирования
argparse
вlib/test/test_argparse.py
источник
parse_args
ВыдаетSystemExit
и печатает в stderr, вы можете поймать оба из них:Вы проверяете stderr (используя,
err.seek(0); err.read()
но, как правило, гранулярность не требуется.Теперь вы можете использовать
assertTrue
любое тестирование:В качестве альтернативы вы можете перехватить и выбросить другую ошибку (вместо
SystemExit
):источник
При передаче результатов из
argparse.ArgumentParser.parse_args
функции я иногда используюnamedtuple
аргументы для проверки аргументов.источник
Для тестирования CLI (интерфейса командной строки), а не вывода команд, я сделал что-то вроде этого
источник