Подтвердить что ты не робот

Обеспечение загрузки 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, но я не вижу объяснения этой проблемы или того, что рекомендуется для ее решения.

4b9b3361

Ответ 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