Где размещать юнит-тесты на Python? [закрыто]
Вопрос о размещении файлов тестов в проекте
Я разрабатываю библиотеку (или приложение) и столкнулся с вопросом: куда лучше размещать файлы модульных тестов?
Хотя будет разумно отделить файлы тестов от основного кода приложения, создание подпапки "tests" внутри корневой директории приложения может привести к некоторым неудобствам. В частности, это усложняет импорт модулей, которые нужно тестировать.
Существует ли лучшая практика для организации файлов тестов в проекте?
5 ответ(ов)
Мы задавались тем же вопросом, когда разрабатывали Pythoscope (https://pypi.org/project/pythoscope/), который генерирует модульные тесты для программ на Python. Мы провели опрос среди участников списка по тестированию в Python, прежде чем выбрать директорию, и получили множество мнений. В итоге мы решили создать директорию "tests" в том же каталоге, где находится исходный код. В этой директории мы генерируем тестовый файл для каждого модуля в родительском каталоге.
Я также склонен размещать свои модульные тесты в самом файле, как отмечает выше Джереми Кантрелл, хотя обычно я не помещаю функцию теста в основное тело, а скорее помещаю всё в блок
if __name__ == '__main__':
# выполнить тесты...
Это добавляет документацию в файл в виде «примера кода» о том, как использовать python-файл, который вы тестируете.
Также стоит отметить, что я стараюсь писать очень компактные модули и классы. Если ваши модули требуют очень большого количества тестов, вы можете разместить их в другом файле, но даже в этом случае я бы всё равно добавил:
if __name__ == '__main__':
import tests.thisModule
tests.thisModule.runtests()
Это позволяет всем, кто читает ваш исходный код, знать, где искать тестовый код.
В вашем случае вы используете директорию tests/
, а затем импортируете основные модули приложения с помощью относительных импортов. Например, в файле MyApp/tests/foo.py
может быть следующий код:
from .. import foo
Это позволяет вам импортировать модуль foo
из пакета MyApp
. Однако стоит отметить, что использование относительных импортов может привести к проблемам с производительностью и читаемостью, если структура вашего приложения станет более сложной. Если вы столкнулись с ошибками в импорте, убедитесь, что ваша рабочая директория настроена правильно и что вы запускаете тесты в контексте пакета. Альтернативным решением может быть использование абсолютных импортов:
from MyApp import foo
Это может улучшить ясность кода и упростить его поддержку. Не забудьте также убедиться, что ваша структура директорий и файл __init__.py
находятся на месте, чтобы Python мог корректно распознать ваши пакеты.
Я не думаю, что существует общепринятая "лучшая практика".
Я помещаю свои тесты в отдельную директорию, которая находится вне кода приложения. Затем я добавляю главную директорию приложения в sys.path (что позволяет импортировать модули откуда угодно) в своем скрипте для запуска тестов (который выполняет и другие задачи) перед запуском всех тестов. Таким образом, мне никогда не нужно убирать директорию с тестами из основного кода перед релизом, что экономит мне время и усилия, пусть и в малой степени.
На основании моего опыта разработки тестовых фреймворков на Python, я бы рекомендовал размещать юнит-тесты в отдельной директории. Поддерживайте симметричную структуру каталогов. Это будет полезно для упаковки только основных библиотек и исключения юнит-тестов из пакета. Ниже представлена схема данного подхода:
<Главный пакет>
/ \
/ \
lib tests
/ \
[module1.py, module2.py, [ut_module1.py, ut_module2.py,
module3.py module4.py, ut_module3.py, ut_module4.py]
__init__.py]
Таким образом, при упаковке этих библиотек с использованием rpm, вы сможете упаковать только основные модули библиотеки (только их). Это значительно улучшает поддержку и управляемость, особенно в условиях Agile-разработки.
Как протестировать, что функция Python вызывает исключение?
Запуск unittest с типичной структурой каталогов тестирования
Написание модульных тестов на Python: С чего начать? [закрыто]
Работают ли параметризованные тесты pytest с тестами на основе классов unittest?
Python Unit Testing: Автоматический запуск отладчика при сбое теста