Pytest не может импортировать модуль, в то время как Python может
Я работаю над пакетом в Python. Я использую virtualenv. Я установил путь к корню модуля в пути .pth в моем virtualenv, чтобы я мог импортировать модули пакета во время разработки кода и проводить тестирование (Вопрос 1: это хороший способ сделать?). Это прекрасно работает (вот пример, это поведение, которое я хочу):
Однако, если я пытаюсь использовать PyTest, я получаю несколько сообщений об ошибках импорта:
Я немного озадачен, похоже, это указывает на ошибку импорта, но Python делает это хорошо, так почему есть проблема именно с PyTest? Любое предложение по причине / средствам защиты (Вопрос 2)? Я погуглил и переполнил стек «Ошибка ImportError: не могу импортировать» для PyTest, но полученные мной попадания были связаны с отсутствием пути к питону и исправлением этой проблемы, которая, по-видимому, здесь не является проблемой. Какие-либо предложения?
20 ответов
НЕ помещайте файл __init__.py в папку, содержащую ИСПЫТАНИЯ, если вы планируете использовать pytest. У меня был один такой файл, удаление которого решило проблему.
Это было на самом деле скрыто в комментариях ко второму ответу на проблему PATH с pytest ‘ImportError: нет модуля с именем YadaYadaYada’, поэтому я его не видел, надеюсь, он получит больше видимости здесь.
Отредактируйте ваш conftest.py и добавьте следующие строки кода:
И если вы пытаетесь запустить тестовый пример через терминал, используйте следующую команду ex:
Если вам нужен файл init .py в вашей папке, сделайте копию этой папки и удалите init .py в ней, чтобы запустить свои тесты, это работает для локальных проектов. Если вам нужно регулярно запускать тестирование, посмотрите, можете ли вы переместить ваш init .py в отдельный файл.
Если у вас уже есть файлы .pyc, попробуйте удалить их.
Сегодня я сталкиваюсь с этой проблемой, вот что произошло:
Сначала я запускаю pytest в mac (это сгенерирует pyc-файлы), затем я запускаю докер-контейнер (os является alpine) с монтированным проектом dir, а затем, когда я пытаюсь запустить pytest в контейнере, происходит ImportError. после очистки всех pyc файлов ошибок больше нет.
Надеюсь, это может быть полезно.
Для тех, кто все перепробовал и все еще получает ошибку, у меня есть обходной путь.
В папке , где установлен pytest , перейдите в папку pytest-env .
Откройте файл pyvenv.cfg .
В файле измените include-system-site-packages с false на true .
Надеюсь, что это работает. Не забудьте проголосовать.
Возможно, что Pytest не читает пакет как модуль Python, в то время как Python (вероятно, из-за проблем с путями). Попробуйте изменить каталог скрипта pytest или явно добавить модуль в PYTHONPATH.
Или может быть, что на вашем компьютере установлены две версии Python. Проверьте исходный код Python на наличие pytest и на наличие оболочки python, которую вы запускаете. Если они отличаются (то есть Python 2 против 3), используйте source activate , чтобы убедиться, что вы запускаете pytest, установленный для того же питона, в котором установлен модуль.
Я столкнулся с этой проблемой сегодня и решил ее, вызвав python -m pytest из корневого каталога моего проекта.
Вызов pytest из того же места по-прежнему вызывал проблемы.
Мой проект DIR организован как:
Модуль routes был импортирован в мой test_routes.py как: from server.routes.routes import Routes
Надеюсь, это поможет!
Я получил это с помощью VSCode. У меня есть среда Конда. Я не думаю, что расширение Python VScode могло видеть обновления, которые я делал.
Я должен был бежать pip install ./ —upgrade
Если это связано с кодом Python, который был первоначально разработан в Python 2.7 и теперь мигрировал в Python 3.x, то проблема, вероятно, связана с проблемой импорта.
Например при импорте объекта из файла: base , который находится в том же каталоге, это будет работать в python 2.x:
В Python 3.x вы должны заменить полный путь base или .base невыполнение этого вызовет вышеуказанную проблему. поэтому постарайтесь:
У меня была похожая проблема, и она работала, когда я добавил файл init .py в каталог тестов.
Еще один особый случай:
У меня была проблема с использованием токсинов. Так что моя программа работала нормально, но юнит-тесты через токсины продолжали жаловаться. После установки пакетов (необходимых для программы) вам необходимо дополнительно указать пакеты, используемые в unittests, в tox.ini
[ Решено ] Прежде чем перейти непосредственно к решению удаления / добавления __init__.py , мы могли бы также посмотреть, как выполняется импорт в ваших классах. На самом деле, я потерял день, играя с одним __init__.py , думая, что это может быть проблемой 🙂 Однако, это было довольно информативно.
В моем случае это был неправильный способ вызова классов из одного класса python в другой класс python, который выбрасывал ImportError . Исправлен способ вызова классов / модулей, и он работал как шарм. Надеюсь, это поможет и другим.
И да, для аналогичной ошибки у нас могут быть разные решения в зависимости от того, как написан код. Лучше потратить больше времени на самостоятельную отладку. Урок усвоен 🙂 Удачного кодирования .
Ответ выше не работает для меня. Я просто решил эту проблему, добавив абсолютный путь к модулю, который не найден, к sys.path в верхней части test_xxx.py (вашего тестового модуля), например:
В моем случае произошла ошибка импорта, поскольку пакет указывает на другой пакет / каталог с тем же именем , а его путь находится на один уровень выше папки, которую я на самом деле хотел. Я думаю, это также объясняет, почему некоторым людям нужно удалить _ init _.py, в то время как другим нужно добавить обратно.
Я просто поместил print(the_root_package.__path__) (после import the_root_package ) в консоли python и pytest , чтобы сравнить разницу
НИЖНЯЯ ЛИНИЯ: Когда вы делаете python , пакет, который вы импортируете, может отличаться от пакета, когда вы запускаете pytest .
Установите пакеты в свою виртуальную среду.
Затем запустите новую оболочку и создайте исходный код для своей виртуальной среды.
У меня была похожая проблема, точно такая же ошибка, но другая причина. Я выполнил тестовый код просто отлично, но против старой версии модуля. В предыдущей версии моего кода один класс существовал, а другой — нет. После обновления моего кода я должен был выполнить следующее, чтобы установить его.
sudo pip install ./ —upgrade
После установки обновленного модуля запуск Pytest дал правильные результаты (потому что я использовал правильную базу кода).
Эта проблема произойдет, если у вас есть tests.py файл и папка с тестами tests/__init__.py .
Во время сбора pytest находит папку, но когда она пытается импортировать тестовые файлы из папки, файл tests.py вызовет проблему с импортом.
Для исправления просто удалите файл tests.py и поместите все свои тесты в папку tests/ .
Для вашего конкретного случая исправление будет точно:
- Удалить файл /home/zz/Desktop/GitFolders/rc/tests.py
- Убедитесь, что /home/zz/Desktop/GitFolders/rc/tests/__init__.py присутствует
У меня была та же проблема, но по другой причине, чем упомянутые:
Я установил py.test глобально, а пакеты были установлены в виртуальной среде.
Решением было установить pytest в виртуальной среде. (Если ваша оболочка хэширует исполняемые файлы, как это делает Bash, используйте hash -r или используйте полный путь к py.test )
Я только что решил эту проблему, удалив __init__.py в корне моего проекта:
Не могу сказать, что понимаю, почему это работает, но у меня была та же проблема, и тесты работают нормально, если я запускаю python -m pytest .
Я в virtualenv, с pytest, также доступным по всему миру:
Источник
Правильный импорт с помощью pytest
Я только что настроился использовать pytest с Python 2.6. До сих пор он работал хорошо, за исключением обработки операторов «import»: я не могу заставить pytest реагировать на импорт так же, как моя программа.
мой структура каталогов выглядит следующим образом:
бежать, я называю python main.py из src/.
In main.py, я импортирую как вектор, так и регион с
In vector.py, я импортирую регион с
все это отлично работает, когда я запускаю код в стандартном запуске. Однако, когда я называю «пы.тест » из src/, он последовательно завершается с ошибками импорта.
некоторые проблемы и мои попытки решения
моей первой проблемой было то, что при запуске «test/test_foo.py», пай.тест не может «foo.py импорт» напрямую. Я решил это с помощью инструмента «чертенок». В «test_util.py»:
это отлично работает для многих файлов. Это также похоже, это означает, что когда pytest работает «path/test/test_foo.py» чтобы проверить «path/foo.py», он базируется в каталоге «путь».
однако это не удается для «test_vector.py». Pytest может найти и импортировать vector модуль, но это не может найти vector ‘ы импорта. Следующий импорт (из «vector.py») оба терпят неудачу при использовании pytest:
они оба дают ошибки формы
Я не знаю, что делать дальше решить эту проблему; мое понимание импорта в Python ограничено.
как правильно обрабатывать импорт при использовании pytest?
Edit: Чрезвычайно Хакерское Решение
на vector.py , я изменил оператор импорта с
это делает импорт относительно каталога «vector.py».
далее, в «test/test_vector.py», я добавляю каталог of «vector.py» на тропинку так:
это позволяет Python найти «../region.py » от «geom/test/test_vector.py».
это работает, но это кажется чрезвычайно проблематичным, потому что я добавляю тонну новых каталогов в путь. Что я ищу-это либо
1) стратегия импорта, совместимая с pytest, или
2) опция в pytest, которая делает его совместимым с моей стратегией импорта
так я оставляя этот вопрос открытым для ответов такого рода.
3 ответов
импорт ищет в следующих каталогах, чтобы найти модуль:
- на домашний каталог программы. Это каталог вашего корневого скрипта. Когда вы используете pytest, ваш домашний каталог находится там, где он установлен (/usr/local/bin вероятно). Независимо от того, что вы запускаете его из каталога src, потому что местоположение вашего pytest определяет ваш домашний каталог. Вот почему он не находит модули.
- PYTHONPATH. Это переменная окружения. Вы можете установить его из командной строки операционной системы. В системах Linux/Unix вы можете сделать это, выполнив: ‘ экспорт PYTHONPATH= / ваш / пользовательский / путь ‘ Если вы хотите, чтобы Python нашел ваши модули из тестового каталога, вы должны включить путь src в эту переменную.
- на стандартные библиотеки . Это каталог, в котором находятся все ваши библиотеки установленный.
- есть менее распространенный вариант с использованием pth .
sys.путь является результатом объединения домашний каталог, PYTHONPATH и стандартные библиотеки
мне тоже было интересно, что делать с этой проблемой. Прочитав этот пост и немного поиграв, я придумал элегантное решение. Я создал файл под названием «test_setup.py-и введите в него следующий код:—5—>
Я поместить этот файл в каталог верхнего уровня (например, src). Когда pytest запускается из каталога верхнего уровня, он будет запускать все тестовые файлы, включая этот, так как файл имеет префикс «test». В файле нет тестов, но он все еще выполняется так как он начинается с «теста».
код добавит текущее имя каталога test_setup.py файл в системный путь в тестовой среде. Это будет сделано только один раз, поэтому к пути не добавляется куча вещей.
затем из любой тестовой функции вы можете импортировать модули относительно этой папки верхнего уровня (например, import geom.region ) и он знает, где его найти, так как каталог src был добавлен в путь.
если вы хотите запустить один тестовый файл (например, test_util.py) вместо всех файлов, вы можете использовать:
это запускает код test_setup и test_util, чтобы код test_setup все еще можно было использовать.
проблема здесь в том, что Pytest ходит по файловой системе, чтобы обнаружить файлы, содержащие тесты, но затем необходимо сгенерировать имя модуля, которое вызовет import чтобы загрузить этот файл. (Помни,файлы не модули.)
Pytest придумывает это тестового пакета имя, найдя первый каталог на уровне или выше уровня файла, который не включает __init__.py файл и объявление, что «basedir» для дерева модулей, содержащего модуль генерируется из этого файла. Затем он добавляет basedir к передней части sys.path и импортирует, используя имя модуля, которое найдет этот файл относительно basedir.
есть некоторые последствия этого, которых вы должны остерегаться:
basepath может не соответствовать вашему предполагаемому basepath, и в этом случае модуль будет иметь имя, которое не соответствует тому, что вы обычно используете. Например, что вы думаете о geom.test.test_vector на самом деле будет называться просто test_vector во время пробега Pytest, потому что он не нашел __init__.py на src/geom/test/ и так добавил, что на пути.
вы можете столкнуться с коллизиями имен модулей, если два файла в разных каталогах имеют одинаковое имя. Например, не хватает __init__.py файлы в любом месте, добавив geom/test/test_util.py будет конфликт с test/test_util.py потому что оба загружаются как import test_util.py , С test/ и geom/test/ в путь.
система, которую вы используете здесь, без явного __init__.py модули, имеет Python create неявные пакеты пространств имен для своих каталогов. (Пакет-это модуль с подмодулями.) В идеале мы бы настроили Pytest с путем, из которого он также будет генерировать это, но он, похоже, не знает, как это сделать.
самое простое решение здесь — просто добавить пустой __init__.py файлы в поддиректории src/ ; это заставит Pytest импортировать все, используя имена пакетов / модулей, которые начинаются с каталога имена под src/ .
Источник
pytest не может импортировать модуль, пока python может
Я работаю над пакетом в Python. Я использую виртуальное окружение. Я установил путь к корню модуля в a .PTH-путь в моем virtualenv, чтобы я мог импортировать модули пакета при разработке кода и выполнять тестирование (Вопрос 1: это хороший способ сделать?). Это отлично работает (вот пример, это поведение, которое я хочу):
однако, если я попытаюсь использовать PyTest, я получу некоторые сообщения об ошибках импорта:
Я немного озадачен, Это выглядит так указывает на ошибку импорта, но Python делает это хорошо, так почему есть проблема именно с PyTest? Любые предложения относительно причины / средства правовой защиты (Вопрос 2)? Я погуглил и стек переполнен ошибкой «ImportError: не могу импортировать» для PyTest, но хиты, которые я получил, были связаны с отсутствующим путем python и исправлением этого, что, похоже, не является проблемой здесь. Есть предложения?
9 ответов
Не ставьте __init__.py файл в папке, содержащей тесты, Если вы планируете использовать pytest. У меня был один такой файл, удаление его решило проблему.
Это было фактически похоронено в комментариях ко второму ответу проблема пути с pytest ‘ImportError: нет модуля с именем YadaYadaYada’ поэтому я его не видел, надеюсь, что здесь будет больше видимости.
Я не могу сказать, что я понимаю, почему это работает, но у меня была та же проблема и тесты работают нормально, если я запустить python -m pytest .
Я в virtualenv, с pytest также доступны по всему миру:
у меня была та же проблема, но по другой причине, чем упомянутые:
у меня был пай.тестирование установлено глобально, в то время как пакеты были установлены в виртуальной среде.
решение было установка pytest в виртуальной среде. (Если ваша оболочка хэширует исполняемые файлы, как это делает Bash, используйте hash -r , или используйте полный путь к py.test )
Я просто решил это, удалив __init__.py в моем проекте root:
эта проблема произойдет, если у вас есть tests.py файл и папка тестов с tests/__init__.py .
во время сбора pytest находит папку, но при попытке импортировать тестовые файлы из папки tests.py файл вызовет проблему импорта.
чтобы исправить, просто удалите tests.py файл и поместите все свои тесты внутри .
для вашего конкретного случая исправление будет точно:
- удалить файл /home/zz/Desktop/GitFolders/rc/tests.py
- убедится /home/zz/Desktop/GitFolders/rc/tests/__init__.py присутствует
в моем случае произошла ошибка импорта, потому что пакет указывает на другой пакет / каталог с то же имя и его путь на один уровень выше папки, которую я действительно хотел. Я думаю, это также объясняет, почему некоторым людям нужно удалить _ init _.py в то время как другие должны добавить обратно.
Я просто ставлю print(the_root_package.__path__) (после import the_root_package ) в и pytest скрипты для сравнения разница
НИЖНЯЯ СТРОКА: Когда вы делаете python , импортируемый пакет может отличаться от пакета при запуске pytest .
возможно, Pytest не читает пакет как модуль Python, в то время как Python (вероятно, из-за проблем пути). Попробуйте изменить каталог скрипта pytest или явно добавить модуль в PYTHONPATH.
или может быть, что у вас есть две версии Python, установленные на вашем компьютере. Проверьте источник Python для pytest и для оболочки python, которую вы запускаете. Если они разные (например, Python 2 vs 3), Используйте source activate чтобы убедиться, что вы используете pytest установлен для того же python, в котором установлен модуль.
У меня была аналогичная проблема, точно такая же ошибка, но другая причина. Я запускал тестовый код просто отлично, но против старой версии модуля. В предыдущей версии моего кода один класс существовал, а другой-нет. После обновления моего кода я должен был запустить следующее, Чтобы установить его.
sudo pip install ./ —upgrade
при установке обновленного модуля под управлением pytest получены правильные результаты (потому что я использовал правильную базу кода).
установите пакеты в виртуальную среду.
Затем запустите новую оболочку и снова создайте виртуальную среду.
Источник