pytest не может импортировать модуль, в то время как python может
Я работаю над пакетом на Python. Я использую virtualenv. Я устанавливаю путь к корню модуля в пути.pth в моем virtualenv, чтобы я мог импортировать модули пакета при разработке кода и тестировании (вопрос 1: это хороший способ сделать?). Это отлично работает (вот пример, это поведение, которое я хочу):
(VEnvTestRc) [email protected]:~/Desktop/GitFolders/rc$ python
Python 2.7.12 (default, Jul 1 2016, 15:12:24)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> from rc import ns
>>> exit()
(VEnvTestRc) [email protected]:~/Desktop/GitFolders/rc$ python tests/test_ns.py
issued command: echo hello
command output: hello
Однако, если я пытаюсь использовать PyTest, я получаю сообщения об ошибках импорта:
(VEnvTestRc) [email protected]:~/Desktop/GitFolders/rc$ pytest
=========================================== test session starts ============================================
platform linux2 -- Python 2.7.12, pytest-3.0.5, py-1.4.31, pluggy-0.4.0
rootdir: /home/zz/Desktop/GitFolders/rc, inifile:
collected 0 items / 1 errors
================================================== ERRORS ==================================================
________________________________ ERROR collecting tests/test_ns.py ________________________________
ImportError while importing test module '/home/zz/Desktop/GitFolders/rc/tests/test_ns.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests/test_ns.py:2: in <module>
from rc import ns
E ImportError: cannot import name ns
!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! Interrupted: 1 errors during collection !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
========================================= 1 error in 0.09 seconds ==========================================
(VEnvTestRc) [email protected]:~/Desktop/GitFolders/rc$ which pytest
/home/zz/Desktop/VirtualEnvs/VEnvTestRc/bin/pytest
Я немного озадачен, похоже, что это указывает на ошибку импорта, но Python делает это хорошо, так почему возникает проблема с PyTest? Любое предложение по причине/исправлению (вопрос 2)? Я googled и stack-overflowed ошибка "ImportError: не могу импортировать" для PyTest, но полученные мной хиты были связаны с отсутствием пути python и средством для этого, что, похоже, не является проблемой здесь. Какие-либо предложения?
Ответы
Ответ 1
Нашел ответ:
НЕ помещайте файл __init__.py
в папку, содержащую TESTS, если вы планируете использовать pytest. У меня был один такой файл, и он решил проблему.
Это было фактически похоронено в комментариях к второму ответу проблемы PATH с pytest 'ImportError: Нет модуля с именем YadaYadaYada', поэтому я не видел его, надеюсь, что он получит большую видимость здесь.
Ответ 2
Я не могу сказать, что понимаю, почему это работает, но у меня была та же проблема, и тесты работают нормально, если я запускаю python -m pytest
.
Я нахожусь в виртуальном мире, и pytest также доступен по всему миру:
(proj)[email protected] ~/dev/proj$ type -a python
python is /home/tom/.virtualenvs/proj/bin/python
python is /usr/bin/python
(proj)[email protected] ~/dev/proj$ python -V
Python 3.5.2
(proj)[email protected] ~/dev/proj$ type -a pytest
pytest is /home/tom/.virtualenvs/proj/bin/pytest
pytest is /usr/bin/pytest
(proj)[email protected] ~/dev/proj$ pytest --version
This is pytest version 3.5.0, imported from /home/tom/.virtualenvs/proj/lib/python3.5/site-packages/pytest.py
Ответ 3
Я просто решил это, удалив __init__.py в моем корне проекта:
.
├── __init__.py <--- removed
├── models
│ ├── __init__.py
│ ├── address.py
│ ├── appointment.py
│ └── client.py
├── requirements.txt
├── setup.cfg
├── tests
│ ├── __init__.py
│ ├── models
│ │ ├── __init__.py
│ │ ├── appointment_test.py
│ │ └── client_test.py
│ └── other_test.py
└── script.py
Ответ 4
У меня была такая же проблема, но по другой причине, чем упомянутые:
У меня был установлен py.test во всем мире, а пакеты были установлены в виртуальной среде.
Решением было установить pytest
в виртуальной среде. (Если ваша оболочка хэширует исполняемые файлы, как это делает Bash, используйте hash -r
или используйте полный путь к py.test
)
Ответ 5
Эта проблема возникает, если у вас есть файл tests.py
и tests.py
папка с tests/__init__.py
.
Во время сбора pytest находит папку, но когда он пытается импортировать тестовые файлы из папки, файл tests.py
вызовет проблему с импортом.
Чтобы исправить, просто удалите файл tests.py
и поместите все ваши тесты в tests.py
tests/
папку.
Для вашего конкретного случая исправление будет точно:
- Удалите файл
/home/zz/Desktop/GitFolders/rc/tests.py
- Убедитесь, что присутствует
/home/zz/Desktop/GitFolders/rc/tests/__init__.py
Ответ 6
У меня была аналогичная проблема, такая же ошибка, но другая причина. Я просто запускал тестовый код, но против старой версии модуля. В предыдущей версии моего кода существовал один класс, а другой - нет. После обновления моего кода я должен был запустить следующее, чтобы установить его.
sudo pip install. / --upgrade
При установке обновленного модуля, на котором запущен pytest, были получены правильные результаты (потому что я использовал правильную базу кода).
Ответ 7
Установите пакеты в свою виртуальную среду.
Затем снова запустите новую оболочку и источник вашей виртуальной среды.
Ответ 8
В моем случае возникла ошибка импорта, потому что пакет указывает на другой каталог/каталог с тем же именем, и его путь на один уровень выше той папки, которую я действительно хотел. Я думаю, это также объясняет, почему некоторым людям нужно удалить _ init _.py, а другим нужно добавить обратно.
Я просто поместил print(the_root_package.__path__)
(после import the_root_package
) в скрипты python
и pytest
чтобы сравнить разницу
BOTTOM LINE: Когда вы выполняете python
, импортируемый вами пакет может отличаться от пакета при запуске pytest
.
Ответ 9
Ответ выше не работает для меня. Я просто решил эту проблему, добавив абсолютный путь к модулю, который не найден, в sys.path
вверху test_xxx.py
(ваш тестовый модуль), например:
import sys
sys.path.append('path')
Ответ 10
У меня была похожая проблема, и она работала, когда я добавил файл init.py в каталог тестов.
Ответ 11
Я получил это с помощью VSCode. У меня есть среда Конда. Я не думаю, что расширение Python VScode могло видеть обновления, которые я делал.
python c:\Users\brig\.vscode\extensions\ms-python.python-2019.9.34911\pythonFiles\testing_tools\run_adapter.py discover pytest -- -s --cache-clear test
Test Discovery failed:
Я должен был бежать pip install ./ --upgrade
Ответ 12
Отредактируйте свой conftest.py и добавьте следующие строки кода:
import os, sys
sys.path.insert(0, os.path.abspath(os.path.join(os.path.dirname(file), '..')))
А если вы пытаетесь запустить тестовый пример через терминал, используйте следующую команду:
python -m pytest test_some_step_file_steps.py --html=HTML_step_file_output.html --self-contained-html
Ответ 13
Возможно, Pytest не читает пакет как модуль Python, в то время как Python (вероятно, из-за проблем с пути). Попробуйте изменить каталог сценария pytest или добавить модуль явно в PYTHONPATH.
Или может быть, у вас на вашем компьютере установлены две версии Python. Проверьте свой источник Python для pytest и для оболочки python, которую вы запускаете. Если они разные (например, Python 2 vs 3), используйте source activate
чтобы убедиться, что вы используете pytest, установленный для того же самого питона, на котором установлен модуль.
Ответ 14
Для тех, кто все перепробовал и все еще получает ошибку, у меня есть обходной путь.
В папке, где установлен pytest, перейдите в папку pytest-env.
Откройте файл pyvenv.cfg.
В этом файле измените include-system-site-packages с false на true.
home = /usr/bin
include-system-site-packages = true
version = 3.6.6
Надеюсь, что это работает. Не забудьте проголосовать.
Ответ 15
Еще один особый случай:
У меня была проблема с использованием токсинов. Так что моя программа работала нормально, но юнит-тесты через токсины продолжали жаловаться. После установки пакетов (необходимых для программы) вам необходимо дополнительно указать пакеты, используемые в unittests, в tox.ini
[testenv]
deps =
package1
package2
...
Ответ 16
Если у вас уже есть файлы .pyc, попробуйте удалить их.
Сегодня я сталкиваюсь с этой проблемой, вот что произошло:
сначала я запускаю pytest в mac (это сгенерирует pyc файлы), затем я запускаю докер-контейнер (os является alpine) с монтированным каталогом проекта, а затем, когда я пытаюсь запустить pytest в контейнере, происходит ImportError. после очистки всех pyc файлов ошибок больше нет.
Надеюсь, что это может быть полезно.
Ответ 17
Я обнаружил, что проблема в том, что pytest не ищет в тех же каталогах, что и python, выполняющийся в виртуальном каталоге.
Моя установка: код Visual Studio, среда PythonVirtual и pytest. Я создал каталог виртуальной среды, и когда pytest выполняется в этой среде, sys.path указывает на этот каталог. Однако я не хотел загромождать свое рабочее пространство кода Visual Studio тем, что обычно находится в виртуальной среде (например, каталогами Lib, Include, Scripts). Поэтому я создал новый каталог рабочей области VS Code в каталоге виртуальной среды. Это подтолкнуло все вниз на один уровень. Visual Studio и Python могут найти каталог моего пакета просто отлично, но pytest ищет один каталог "слишком высоко", даже когда он запускается VS Code.
Я временно исправил это, добавив путь к каталогу моей рабочей области в sys.path вверху файла "test_xyz.py".
Ответ 18
Если это связано с кодом Python, который был изначально разработан в Python 2.7, а теперь перенесен в Python 3.x, то проблема, вероятно, связана с проблемой импорта.
например
при импорте объекта из файла: base
, который находится в том же каталоге, это будет работать в python 2.x:
from base import MyClass
в Python 3.x вы должны заменить полный путь base
или .base
невыполнение этого вызовет вышеуказанную проблему.
так что попробуйте:
from .base import MyClass
Ответ 19
если вам нужен файл init.py в вашей папке, сделайте копию этой папки и удалите init.py в этой папке, чтобы запустить свои тесты, она работает для локальных проектов. Если вам нужно регулярно запускать тестирование, посмотрите, можете ли вы переместить ваш init.py в отдельный файл.
Ответ 20
[Решено]
Прежде чем перейти непосредственно к решению удаления/добавления __init__.py
, мы также можем посмотреть, как выполняется импорт в ваших классах. На самом деле, я потерял день, играя с одним __init__.py
, думая, что это может быть проблемой :) Однако, это было довольно информативно.
В моем случае это был неправильный способ вызова классов из одного класса python в другой класс python, который выбрасывал ImportError
. Исправлен способ вызова классов/модулей, и он работал как шарм. Надеюсь, это поможет и другим.
И да, для аналогичной ошибки у нас могут быть разные решения в зависимости от того, как написан код. Лучше потратить больше времени на самостоятельную отладку. Урок усвоен :) Удачного кодирования !!!