Импорт Python для тестов с использованием носа - что является лучшим методом для импорта модулей выше текущего пакета - PullRequest
61 голосов
/ 12 июля 2011

Это вопрос, который часто задают в разных формах и часто получают ответы «лол, ты не правильно делаешь». Я уверен, что это потому, что есть сценарий здравого смысла, который люди (включая меня) пытаются использовать в качестве реализации, и решение не очевидно (если вы не делали этого раньше).

Принял бы ответ, который "позволяет летать из бутылки".

С учетом

project/
    __init__.py
    /code
        __init__.py
        sut.py
    /tests
        __init__.py
        test_sut.py

Где начинается tests_sut.py:

import code.sut

Запуск тестов носа в корневом каталоге приводит к:

ImportError: No module named code.sut

Пройденные пути:

а) сделать родственника, используя

from ..code import sut

б) добавить корень проекта в PYTHONPATH

в) используйте

sys.path.append

для добавления пути .. перед импортом в начале каждого тестового модуля.

г) просто не забудьте сделать

setup.py 

в проекте по установке модулей в site-пакеты перед запуском тестов.

<Ч />

Таким образом, требуется, чтобы тесты располагались под корнем тестового пакета и имели доступ к проекту. Все вышеперечисленное не кажется мне «естественным», оказалось проблематичным или кажется слишком тяжелым трудом!

В Java это работает, но в основном благодаря инструменту сборки / IDE, помещающему все ваши классы в путь к классам. Возможно, проблема в том, что я ожидаю "магии" от Python? Как уже отмечалось в тестах веб-фрейма Flask, вариант d) представляется предпочтительным.

В любом случае приведенные ниже утверждения, рекомендующие предпочтительное решение, устранят ощущение "неестественности" в моем собственном.

Ответы [ 3 ]

44 голосов
/ 18 мая 2012

У меня была та же проблема, и я нашел ответ в связанной работе для меня.

Просто удалите __init__.py в корне проекта.

10 голосов
/ 13 июля 2011

Вы уже достаточно хорошо ответили на свой вопрос .. D (установка в системную папку) предпочтительнее для распространяемого кода.Я обычно использую C (modify sys.path), потому что я не хочу общесистемных установок моих сотен пользовательских библиотек.В теории А (относительный импорт) кажется лучше, но есть случаи, когда он терпит неудачу.B (PYTHONPATH) подходит, на мой взгляд, действительно только для целей тестирования.

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

На мой взгляд, лучшее, что нужно сделать, это поместить это в точки входа в вашу программу:

import sys, os
sys.path = [os.path.abspath(os.path.dirname(__file__))] + sys.path
4 голосов
/ 18 сентября 2013

Я знаю, что ответ проверен, и я все еще думаю, что это хорошая причина поделиться другими альтернативами:)

Существует path-pathmunge , дающий вам возможность установить sys.path при вызове nosestests.

...