Импортировать родительский каталог для кратких тестов

Я просмотрел этот сайт сверху вниз, но не нашел ни одного способа добиться того, что я хочу, в Python3x. Это простое игрушечное приложение, поэтому я решил, что могу написать несколько простых тестовых случаев в утверждениях и положить этому конец. Он генерирует отчеты и тому подобное, поэтому я хотел бы убедиться, что мой код не делает ничего шаткого при изменениях.

Моя текущая структура каталогов: (включены только соответствующие части)

project
  -model
     __init__.py
     my_file.py
     -test
       my_file_test.py

У меня чертовски много времени, чтобы my_file_test.py импортировал my_file.py.

Как я уже сказал. Я искал этот сайт сверху вниз, и ни одно решение не сработало. Моя версия Python 3.2.3 работает на Fedora 17.

Предыдущие попытки: https://stackoverflow.com/questions/4655526/how-to-accomplish-this-relative-import-in-python Импорт модулей из родительская папка Может ли кто-нибудь объяснить относительный импорт python? Как выполнить относительный импорт в python

Практически при каждой попытке я получаю сообщение об ошибке:

ImportError: Нет модуля с именем * ИЛИ ValueError: Попытка относительного импорта в не-пакете

Что здесь происходит. Я пробовал каждый принятый ответ на SO, а также во всех сетях. Не делая здесь ничего особенного, но как программист .NET/Java/Ruby, это оказывается абсолютным определением интуитивности.

РЕДАКТИРОВАТЬ: Если это имеет значение, я попытался загрузить класс, который я пытаюсь импортировать в REPL, и я получаю следующее:

>>> import datafileclass
>>> datafileclass.methods
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
>>> x = datafileclass('sample_data/sample_input.csv')
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: 'module' object is not callable

Если это имеет значение... Я знаю, что функциональность в классе работает, но я не могу импортировать ее, что в настоящее время вызывает невозможность тестирования. В будущем, безусловно, вызовет проблемы интеграции. (имена изменены, чтобы защитить невиновных) получение в течение пары недель желаемой функциональности для этой итерации библиотеки... любая помощь может быть полезна. Я бы сделал это на Ruby, но клиент хочет использовать Python в качестве учебного опыта.


person Rig    schedule 12.07.2012    source источник


Ответы (1)


Структурируйте свой код следующим образом:

project
  -model
    __init__.py
    my_file.py
  -tests
    __init__.py
    test_my_file.py

Важно отметить, что ваш каталог tests также должен быть каталогом модуля (в нем должен быть пустой файл __init__.py).

Затем в test_my_file.py используйте from model import my_file, а из верхнего каталога запустите python -m tests.test_my_file. Это вызывает test_my_file как модуль, что приводит к тому, что Python настраивает свой путь импорта, чтобы включить ваш верхний уровень.

Еще лучше, вы можете использовать pytest или нос, и запуск py.test автоматически подберет тесты.

Я понимаю, что это не отвечает на ваш вопрос, но вам будет намного проще работать со стандартными практиками Python, а не против них. Это означает структурирование вашего проекта с тестами в их собственном каталоге верхнего уровня.

person ecatmur    schedule 12.07.2012
comment
Спасибо. Я попробую сегодня вечером. Это было похоже на мою первоначальную структуру, но я наткнулся на какой-то ресурс, в котором говорилось, что я должен структурировать его таким образом. Я дам вам знать, как это работает, как только я освобожусь. - person Rig; 12.07.2012
comment
Это вызывает ошибку ImportError: No module named model в строке 1 (оператор импорта). Что не так с этой картинкой. - person Rig; 12.07.2012
comment
Есть ли какие-то явные аннотации, которые мне нужны в моем классе, чтобы сделать его импортируемым? На самом деле не разбираюсь в питоне, и прошло некоторое время с тех пор, как я даже использовал его (тогда он был только в качестве преподавателя). - person Rig; 12.07.2012
comment
... должен ли я иметь содержимое в файле init.py? Кажется, ничто не указывает на то, что в нем должно быть что-то - person Rig; 12.07.2012
comment
@Rig нет, __init__.py может быть пустым. Я забыл указать, что tests также должен иметь __init__.py, и вызывать тесты с использованием синтаксиса -m. - person ecatmur; 13.07.2012
comment
Не идти. python3 -m test.PaypalCSVPayDataFileTest Трассировка (последний последний вызов): Файл /usr/lib64/python3.2/runpy.py, строка 160, в _run_module_as_main main, fname, loader, pkg_name) File / usr/lib64/python3.2/runpy.py, строка 73, в файле _run_code exec(code, run_globals) /media/sf_My_Projects/washmypy/test/PaypalCSVPayDataFileTest.py, строка 8, в файле ‹module› main() /media /sf_My_Projects/washmypy/test/PaypalCSVPayDataFileTest.py, строка 4, в основном файле1 = PaypalCSVPayDataFile('/sample_data/sample_paypal_input.csv') TypeError: объект 'module' не вызывается - person Rig; 17.07.2012
comment
РЕДАКТИРОВАТЬ: я исправлен. Вы были правы, и я нашел не связанную проблему. Спасибо. - person Rig; 17.07.2012
comment
Спасибо за это - это решило мою проблему. Но какой эффект имеет наличие файла init.py в тестовом каталоге? Почему это решает проблему? - person Zxaos; 08.05.2013
comment
@Zxaos, предоставляющий __init__.py, превращает каталог в модуль, позволяя его импортировать. - person ecatmur; 08.05.2013
comment
@ecatmur верно, но я не импортирую тестовый модуль. Почему превращение тестового каталога в модуль исправляет импорт внешнего модуля, который я тестирую? - person Zxaos; 09.05.2013