Тесты и структура пакета Python - PullRequest
8 голосов
/ 04 марта 2011

У меня есть некоторые проблемы в структурировании моего проекта на Python. В настоящее время это куча файлов в одной папке. Я попытался структурировать это как

proj/
  __init__.py
  foo.py
  ...
  bar/
    __init__.py
    foobar.py
    ...
  tests/
    foo_test.py
    foobar_test.py
    ...

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

Я прочитал PEP 328 об относительном импорте и PEP 366 об относительном импорте из основного модуля. Но оба эти метода требуют, чтобы базовый пакет был в моей PYTHONPATH. Действительно я получаю следующую ошибку

ValueError: Попытка относительного импорта в неупакованном виде.

Итак, я добавил следующий шаблонный код поверх тестовых файлов

import os, sys
sys.path.append(os.path.join(os.getcwd(), os.path.pardir))

Тем не менее я получаю ту же ошибку. Какой правильный путь к

  • структурировать пакет с тестами и
  • добавить базовый каталог к ​​пути, чтобы разрешить импорт?

РЕДАКТИРОВАТЬ В соответствии с запросом в комментарии я добавляю пример импорта, который завершается неудачно (в файле foo_test.py)

import os, sys
sys.path.append(os.path.join(os.getcwd(), os.path.pardir))
from ..foo import Foo

Ответы [ 2 ]

12 голосов
/ 05 марта 2011

Когда вы используете переключатель -m для запуска кода, текущий каталог добавляется в sys.path.Таким образом, самый простой способ запустить ваши тесты из родительского каталога proj, используя команду:

python -m proj.tests.foo_test

Чтобы это работало, вам нужно включить файл __init__.py в свой каталог тестов.чтобы тесты были правильно распознаны как часть пакета.

5 голосов
/ 04 марта 2011

Мне нравится, когда это возможно, импортировать модули, используя полный префикс пакета proj.NAME.Такой подход рекомендует Google Python style .

Один из вариантов, который позволит вам сохранить структуру вашего пакета, использовать полные пути к пакетам и все же двигаться вперед в процессе разработки, заключается в использовании virtualenv.и переведите свой проект в режим разработки.setup.py вашего проекта нужно будет использовать setuptools вместо distutils, чтобы получить команду develop.

Это позволит вам избежать вышеупомянутых вещей sys.path.append:

% virtualenv ~/virt
% . ~/virt/bin/activate
(virt)~% cd ~/myproject
(virt)~/myproject% python setup.py develop
(virt)~/myproject% python tests/foo_test.py

Где foo_test.py использует:

from proj.foo import Foo

Теперь, когда вы запустите python изнутри вашего virtualenv, ваш PYTHONPATH будет указывать на все пакеты в вашем проекте.Вы можете создать более короткий псевдоним оболочки, чтобы ввести свой virtualenv, не вводя каждый раз . ~/virt/bin/activate.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...