Я хочу, чтобы мой папка с тестами отдельная был в моем коде приложения. Моя структура проекта такая
myproject/
myproject/
myproject.py
moduleone.py
tests/
myproject_test.py
мой проект.py
from moduleone import ModuleOne
class MyProject(object)
....
мой проект_test.py
from myproject.myproject import MyProject
import pytest
...
Я использую myproject.myproject, так как я использую команду
python -m pytest
из корневого каталога проекта ./myproject/
Однако тогда импорт в этих модулях завершается с ошибкой
E ModuleNotFoundError: No module named 'moduleone'
Я использую Python 3.7 и прочитал, что начиная с 3.3 пустые файлы __init__ больше не нужны, что означает, что мой проект становится неявный пакет пространства имен
Тем не менее, я попытался добавить файл __init__.py в myproject/myproject/, а также попытался добавить файл conftest.py в myproject/, но ни один из них не работает.
У меня есть читать ответы, которые говорят путаться с дорожками, а затем проголосовали за комментарии в других вопросах, говоря не.
Каков правильный путь и что мне не хватает?
РЕДАКТИРОВАТЬ;
Возможно, это связано с тем, что я использовал requirements.txt для установки pytest с помощью pip. Может ли это быть связано? И если да, то как правильно установить pytest в этом случае?
Обновлено еще раз:
Один из путей в sys.path — это /usr/src/app/, который представляет собой том докера, связанный с /my/local/path/myproject/.
Должна ли громкость быть /my/local/path/myproject/myproject/ вместо этого?
Длинные комментарии. Вы также можете (в командной строке) добавить PYTHONPATH, чтобы включить целевой каталог. Это означает, что вам не придется манипулировать sys.path из любого из ваших скриптов, но вы получите обновленный путь при запуске теста. PYTHONPATH=./myproject python -m pytest как будто вы это сделали.
Из каталогов, которые вы перечислили в структуре проекта, какие (если есть) есть в вашем PYTHONPATH?
@JohnGordon обновил вопрос новой информацией
Вы пытались добавить пустой в этом.py в каталог ./tests вместо каталога вашего проекта. Это может показаться странным, но стоит попробовать.






Обязательно включите . точку в $PYTHONPATH env var.
Используйте $ python -m site или этот фрагмент кода для отладки таких проблем:
import pprint
import sys
pprint.pprint(sys.path)
В вашем вопросе удалось использовать myproject на трех разных уровнях. По крайней мере, во время отладки вы можете использовать три разных имени, чтобы уменьшить возможную путаницу.
Таким образом, кажется, что sys.path должен включать каталог приложений, а не корневую папку проекта, содержащую каталог приложения и тестовый каталог.
Так что в моем случае /my/local/path/myproject/myproject/ должно было быть в sys.path, а не /my/local/path/myproject/.
Тогда я мог запустить pytest в /my/local/path/myproject/ (не нужно python -m pytest). Это означало, что модули внутри /myproject/myproject/ могли находить друг друга и тесты без какой-либо вложенности пространств имен.
Так выглядели мои тесты
from moduleone import ModuleOne
import pytest
def test_fun():
assert ModuleOne.example_func() == True
Тем не менее, похоже, что много ошибок, так что я понятия не имею, правильно ли это...
Я также столкнулся с этой проблемой и использую поэзию для управления зависимостями и direnv для переменных среды, специфичных для моего проекта. Обратите внимание, что я относительно новичок в Python, поэтому я не знаю, правильное ли это решение.
Вот весь мой файл .envrc:
layout_poetry() {
if [[ ! -f pyproject.toml ]]; then
log_error 'No pyproject.toml found. Use `poetry new` or `poetry init` to create one first.'
exit 2
fi
local VENV=$(poetry env list --full-path | cut -d' ' -f1)
if [[ -z $VENV || ! -d $VENV/bin ]]; then
log_error 'No created poetry virtual environment found. Use `poetry install` to create one first.'
exit 2
fi
VENV=$VENV/bin
export VIRTUAL_ENV=$(echo "$VENV" | rev | cut -d'/' -f2- | rev)
export POETRY_ACTIVE=1
PATH_add "$VENV"
}
layout poetry
export PYTHONDONTWRITEBYTECODE=1
export PYTHONPATH = "$PWD/project_name"
Я не знаю, нужно ли мне размещать стихи, потому что предполагается, что они уже создают для нас виртуальную среду, но это то, что мне посоветовал коллега, поэтому я согласился. Макетная поэзия тоже не работала без этой функции и ей не понравилось, когда я добавил ее в свой зшенв, поэтому добавил сюда.
Для этого конкретного вопроса последняя строка — это производитель денег.
Сохранил все то же самое и просто добавил пустой тестовый файл в корневую папку. Решено
Вот результаты, эта проблема действительно беспокоила меня какое-то время. Моя структура папок была
mathapp/
- server.py
- configuration.py
- __init__.py
- static/
- home.html
tests/
- functional
- test_errors.py
- unit
- test_add.py
и pytest будет жаловаться на ModuleNotFoundError.
Я представил тестовый файл на том же уровне, что и mathsapp и каталог с тестами. В файле ничего не было. Теперь pytest не жалуется.
Результат без файла
$ pytest
============================= test session starts =============================
platform win32 -- Python 3.8.2, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\mak2006\workspace\0github\python-rest-app-cont
collected 1 item / 1 error
=================================== ERRORS ====================================
_______________ ERROR collecting tests/functional/test_func.py ________________
ImportError while importing test module 'C:\mainak\workspace\0github\python-rest-app-cont\tests\functional\test_func.py'.
Hint: make sure your test modules/packages have valid Python names.
Traceback:
tests\functional\test_func.py:4: in <module>
from mathapp.service import sum
E ModuleNotFoundError: No module named 'mathapp'
=========================== short test summary info ===========================
ERROR tests/functional/test_func.py
!!!!!!!!!!!!!!!!!!! Interrupted: 1 error during collection !!!!!!!!!!!!!!!!!!!!
============================== 1 error in 0.24s ===============================
Результаты с файлом
$ pytest
============================= test session starts =============================
platform win32 -- Python 3.8.2, pytest-5.4.2, py-1.8.1, pluggy-0.13.1
rootdir: C:\mak2006\workspace\0github\python-rest-app-cont
collected 2 items
tests\functional\test_func.py . [ 50%]
tests\unit\test_unit.py . [100%]
============================== 2 passed in 0.11s ==============================
PYTHONPATH. варPYTHONPATH=. pytest
Как уже упоминалось @J_H, вам нужно явно добавить корневой каталог вашего проекта, поскольку pytest добавляется только в sys.path каталоги, в которых находятся тестовые файлы (именно поэтому ответ @Mak2006 сработал).
Если вы не хотите постоянно вводить эту длинную команду, один из вариантов — создать Makefile в корневом каталоге вашего проекта, например, следующим образом:
.PHONY: test
test:
PYTHONPATH=. pytest
Что позволяет вам просто запустить:
make test
Другой распространенной альтернативой является использование какого-либо стандартного инструмента тестирования, такого как отравить.
Небольшое замечание: в make-файлах для отступов требуются табуляции, поэтому копирование вашего кода может не сработать, поскольку в нем используются пробелы.
Спасибо @SilverSlash! В исходном коде на самом деле используются табуляции, но на самом деле в ответе они отображаются как пробелы. Кто-нибудь знает, как это исправить?
Я думаю, что это ограничение HTML и веб-браузеров, к сожалению.
Не уверен, что это решение было специфичным для моей проблемы, но я просто добавляю __init__.py в свою папку tests, и это решило проблему.
Это помогает, спасибо. Могу ли я узнать, почему он меняет поведение импорта pytest, добавляя в этом.py в папку тестов?
В моем случае я добавил __init__.py в свой тестовый каталог с этим внутри:
import sys
sys.path.append('.')
Код моего приложения находится на том же уровне, что и мой тестовый каталог.
Используя поэзию и pytest 5.4.3, у меня была следующая структура (некоторые папки/файлы были удалены для ясности):
.
├── my_app
│ ├── __init__.py
│ ├── main.py
│ ├── model.py
│ └── orm.py
├── poetry.lock
├── pyproject.toml
├── README.rst
└── tests
├── __init__.py
├── conftest.py
├── test_my_app.py
└── utilities
└── db_postgresql_inmemory.py
pytest_plugins = [
"utilities.db_postgresql_inmemory",
]
который сгенерировал ошибку модуля, не найденную для прибора:
ImportError: Error importing plugin "utilities.db_postgresql_inmemory": No module named 'utilities'
Ни один из других ответов не сработал для меня, поскольку я пытался добавить:
[me@linux ~/code/my_app]touch tests/utilities/__init__.py
[me@linux ~/code/my_app]touch ./test_blank.py
Я мог бы заставить импорт из conftest.py работать с УДАЛЕНИЕ обоими __init__.py файлами:
[me@linux ~/code/my_app]rm tests/utilities/__init__.py tests/__init__.py
В моем случае это потому, что я установил pytest на системном уровне, а не в своей виртуальной среде.
Вы можете проверить это по python -m pytest. Если вы видите ModuleNotFoundError: No module named 'pytest', значит ваш pytest находится на системном уровне.
Установите pytest, когда виртуальная среда активирована, это исправит.
В моем случае он установлен как на системном, так и на виртуальном уровне. Но работает только python3 -m pytest.
ДРУГОЕ ПРЕДЛОЖЕНИЕ
Смотрите этот ответ: https://stackoverflow.com/a/69691436/595305
Я столкнулся с проблемой, которую я решил
pytest в корень моего проекта с помощью pip install pytest__init__.py в брате моего test_file.py, который я хотел выполнить.В моем случае я создал отдельное приложение для тестирования __init__.py и conftest.py на одном уровне. После удаления __init__.py ошибка исчезла.
Кредит идет наqci-амос
Честно говоря, это будет война мнений, если что. Вы можете переместить тестовую папку в свою основную структуру и выполнить ее оттуда, и все будет работать как есть. Не нужно ничего менять, поскольку пути импорта будут актуальны. Кроме этого, вам нужно будет исправить путь в тестовых файлах, чтобы включить целевой каталог, и это было бы неплохо (мнение). Просто знайте, почему и что вы делаете.