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. Исправлен способ вызова классов/модулей, и он работал как шарм. Надеюсь, это поможет и другим.

И да, для аналогичной ошибки у нас могут быть разные решения в зависимости от того, как написан код. Лучше потратить больше времени на самостоятельную отладку. Урок усвоен :) Удачного кодирования !!!