Обеспечение загрузки py.test включает каталог приложений в sys.path
У меня есть структура каталога проекта следующим образом (что я считаю довольно стандартным):
my_project
setup.py
mypkg
__init__.py
foo.py
tests
functional
test_f1.py
unit
test_u1.py
Я использую py.test для моей платформы тестирования, и я ожидал, что сможет запустить py.test tests
, когда в каталоге my_project
будут запускаться мои тесты. Это действительно работает, пока я не попытаюсь импортировать код приложения, используя (например) import mypkg
в тесте. В этот момент я получаю сообщение об ошибке "Без модуля с именем mypkg". При выполнении небольшого исследования выясняется, что py.test
запускает тесты с каталогом тестового файла в sys.path
, но не из каталога, из которого py.test
был запущен.
Чтобы обойти это, я добавил файл conftest.py
в мой каталог tests
, содержащий следующий код:
import sys, os
# Make sure that the application source directory (this directory parent) is
# on sys.path.
here = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, here)
Это похоже на работу, но является ли это хорошим способом убедиться, что тесты видят код приложения? Есть ли лучший способ достичь этого, или я делаю что-то неправильно в том, как у меня структурирован мой проект?
Я просмотрел некоторые другие проекты, которые используют py.test
(например, pip
), но я не вижу код, который делает что-то подобное, но пока работает py.test tests
. Я не знаю, почему, но я беспокоюсь, что они, возможно, достигли того же результата более простым способом.
Я просмотрел документацию py.test
, но я не вижу объяснения этой проблемы или того, что рекомендуется для ее решения.
Ответы
Ответ 1
Как вы говорите, py.test в основном предполагает, что вы правильно настроили PYTHONPATH. Существует несколько способов достижения этой цели:
-
Дайте вашему проекту setup.py и используйте pip install -e .
в virtualenv для этого проекта. Это, вероятно, стандартный метод.
-
Как вариант, если у вас есть virtualenv, но нет setup.py, используйте средство venv для добавления каталога проектов на sys.path, например. pew add .
, если вы используете pew или add2virtualenv .
, если используете virtualenv и расширения virtualenvwrapper.
-
Если вам всегда нравится текущий рабочий каталог на sys.path, вы всегда можете экспортировать PYTHONPATH=''
в свою оболочку. Это обеспечивает пустую строку на sys.path, которую python будет интерпретировать как текущую рабочую директиву. Это потенциально опасно для безопасности.
-
Мой собственный любимый хак, злоупотребляйте тем, как py.test загружает файлы conftest: поместите пустой conftest.py
в каталог верхнего уровня проекта.
Причина, по которой py.test ведет себя так, заключается в том, чтобы упростить запуск тестов в каталоге tests/checkout против установленного пакета. Если бы он безоговорочно добавил каталог проекта в PYTHONPATH, это было бы невозможно.
Ответ 2
Ответ на самом деле намного проще, как показано здесь.
Все, что вам нужно сделать, это добавить __init__.py
в тестовый каталог и каждый из его подкаталогов, например:
tests/__init__.py
tests/functional/__init__.py
tests/unit/__init__.py