Проблема PATH с pytest 'ImportError: нет модуля с именем YadaYadaYada'

Я использовал easy_install для установки pytest на mac и начал писать тесты для проекта с файловой структурой:

repo/
repo/app.py
repo/settings.py
repo/models.py
repo/tests/
repo/tests/test_app.py

запустите py.test, в то время как в каталоге репо все ведет себя так, как вы ожидали.

но когда я пытаюсь сделать то же самое на linux или windows (оба имеют pytest 2.2.3 на них), он берется всякий раз, когда он начинает свой первый импорт чего-либо из моего пути к приложению. Скажем, например, from app import some_def_in_app

Нужно ли мне редактировать PATH для запуска py.test в этих системах? Кто-нибудь испытал это?

Ответ 1

Да, исходная папка не находится в пути Python, если вы cd к каталогу тестов.

У вас есть 2 варианта:

  1. Добавьте путь к тестовым файлам вручную, например:

    import sys, os
    myPath = os.path.dirname(os.path.abspath(__file__))
    sys.path.insert(0, myPath + '/../')
    
  2. Запустите тесты с помощью env var PYTHONPATH=../.

Ответ 2

Я не уверен, почему py.test не добавляет текущий каталог в сам PYTHONPATH, но здесь обходной путь (который должен выполняться из корня вашего репозитория):

python -m pytest tests/

Это работает, потому что Python добавляет текущий каталог в PYTHONPATH для вас.

Ответ 3

У меня была та же проблема. Я исправил его, добавив пустой __init__.py файл в мой каталог tests.

Ответ 4

conftest решение

Наименее инвазивное решение - добавить пустой файл с именем conftest.py в conftest.py repo/:

$ touch repo/conftest.py

Это. Нет необходимости писать собственный код для искажения sys.path или не забывать перетаскивать PYTHONPATH вместе или помещать __init__.py в каталоги, где он не принадлежит.

Каталог проекта впоследствии:

repo
├── conftest.py
├── app.py
├── settings.py
├── models.py
└── tests
     └── test_app.py

объяснение

pytest ищет модули conftest в conftest тестов для сбора пользовательских хуков и фикстур, а для импорта из них пользовательских объектов pytest добавляет родительский каталог conftest.py в sys.path.

Другие структуры проекта

Если у вас есть другая структура проекта, поместите conftest.py в корневой каталог пакета (тот, который содержит пакеты, но не сам пакет, поэтому не содержит __init__.py), например:

repo
├── conftest.py
├── spam
│   ├── __init__.py
│   ├── bacon.py
│   └── egg.py
├── eggs
│   ├── __init__.py
│   └── sausage.py
└── tests
     ├── test_bacon.py
     └── test_egg.py

src расположение

Хотя этот подход можно использовать с компоновкой src (поместите conftest.py в conftest.py src):

repo
├── src
│   ├── conftest.py
│   ├── spam
│   │   ├── __init__.py
│   │   ├── bacon.py
│   │   └── egg.py
│   └── eggs 
│       ├── __init__.py
│       └── sausage.py
└── tests
     ├── test_bacon.py
     └── test_egg.py

PYTHONPATH в виду, что добавление src в PYTHONPATH уменьшает значение и преимущества макета src ! Вы закончите тестированием кода из репозитория, а не установленного пакета. Если вам нужно сделать это, возможно, вам вообще не нужен src dir.

Куда пойти отсюда

Конечно, модули conftest - это не просто файлы, помогающие в обнаружении исходного кода; это место, где происходят все специфичные для проекта улучшения платформы pytest и настройка вашего набора тестов. pytest много информации о модулях conftest разбросанных по всем документам; начать с conftest.py: локальные плагины для каждого каталога

Кроме того, у SO есть отличный вопрос по модулям conftest: что такое использование файлов conftest.py в py.test?

Ответ 5

Вы можете запускать PYTHONPATH в корне проекта

PYTHONPATH=. py.test

Или используйте pip install как редактируемый импорт

pip install -e .   # install package using setup.py in editable mode

Ответ 6

Запускать pytest как модуль с помощью: python -m pytest tests

Ответ 7

Я создал это как ответ на ваш вопрос и свое собственное замешательство. Я надеюсь, что это помогает. Обратите внимание на PYTHONPATH как в командной строке py.test, так и в tox.ini.

https://github.com/jeffmacdonald/pytest_test

В частности: вы должны указать py.test и tox, где вы найдете модули, которые вы включаете.

С помощью py.test вы можете сделать это:

PYTHONPATH=. py.test

И с помощью токсичности добавьте это в ваш tox.ini:

[testenv]
deps= -r{toxinidir}/requirements.txt
commands=py.test
setenv =
    PYTHONPATH = {toxinidir}

Ответ 8

Я начал получать weird ConftestImportFailure: ImportError('No module named... ошибки, когда я случайно добавил файл __init__.py в мой каталог src (который не должен был быть пакетом Python, просто контейнером всего источника).

Ответ 9

Я получал эту ошибку из-за чего-то еще более простого (можно даже сказать тривиально). Я не установил модуль pytest. Поэтому простой apt install python-pytest исправил это для меня.

'pytest' был бы указан в setup.py как тестовая зависимость. Убедитесь, что вы также установили требования к тестированию.

Ответ 10

Я исправил это, удалив верхний уровень __init__.py в родительской папке моих источников.

Ответ 11

Для меня проблема была tests.py сгенерированная Django вместе с каталогом tests. Снятие tests.py решило проблему.

Ответ 12

Я получил эту ошибку, так как неправильно использовал относительный импорт. В примере OP test_app.py должен импортировать функции, используя, например,

from repo.app import *

Однако в общем случае файлы __init__.py разбросаны по файловой структуре, это не работает и создает вид импортируемой ошибки, если только файлы и тестовые файлы не находятся в одном каталоге.

from app import *

Вот пример того, что я должен был сделать с одним из моих проектов:

Вот моя структура проекта:

microbit/
microbit/activity_indicator/activity_indicator.py
microbit/tests/test_activity_indicator.py

Чтобы получить доступ к activity_indicator.py из test_activity_indicator.py, мне нужно было:

  • запустите test_activity_indicatory.py с правильным относительным импортом:
    from microbit.activity_indicator.activity_indicator import *
  • поместите файлы __init__.py по всей структуре проекта:
    microbit/
    microbit/__init__.py
    microbit/activity_indicator/__init__.py
    microbit/activity_indicator/activity_indicator.py
    microbit/tests/__init__.py
    microbit/tests/test_activity_indicator.py

Ответ 13

У меня была похожая проблема. pytest не распознал модуль, установленный в среде, в которой я работал.

Я решил это, также установив pytest в той же среде.

Ответ 14

Очень часто тесты прерывались из-за невозможности импорта модуля. После исследования я обнаружил, что система ищет файл в неправильном месте, и мы легко можем решить проблему, скопировав файл, содержащий модуль, в та же папка, как указано, для правильного импорта. Еще одно решение - изменить объявление для импорта и показать MutPy правильный путь к блоку. Однако из-за того, что несколько модулей могут иметь эту зависимость, а это означает, что нам необходимо зафиксировать изменения и в их объявлениях, мы предпочитаем просто переместить модуль в папку.