Структура каталога проекта Python/проблема pytest
Это должна быть самая простая проблема на земле, но даже после обширных поисков и мастеринга я все еще испытываю глубокие затруднения с поиском "правильного" способа заложить структуру каталогов и правильно запустить pytest и т.д.
Скажем, у меня есть программа под названием apple.
|- README.md
|- apple
| |-- __init__.py
| |-- apple.py
| - tests
| |-- test_everything.py
В apple.py содержатся некоторые функции, для примера давайте позвоним один eat()
. И файл test_everything.py
содержит некоторые тесты, такие как assert eat()=="foobar"
. Так хорошо, так легко, но тогда начинается самое интересное:
- Как насчет
__init__.py
в каталоге Apple... правильно? Пусто или что должно быть внутри?
- Лучше ли вызывать
py.test
из корневого каталога? Или py.test tests
?
- Так много проектов имеют
__init__.py
в своем тестовом каталоге, но это явно указано неверно в документации py.test. Так почему Бог почему
- Что находится в верхней части файла
test_everything.py
: a import apple
или from apple import *
? или что-то еще полностью
- Вы вызываете функции тогда
eat()
или apple.eat()
?
- Некоторые даже рекомендуют манипулировать
os.path.dirname
в python
Это должно быть легко, но я видел каждую комбинацию вышеизложенного, даже не говоря о токсике и множестве других инструментов. Однако с малейшей ошибкой вы получаете несколько ImportError: No module named 'apple'
или некоторые другие фанки-ошибки.
Что такое "правильный" способ? Совет и существующий код на github и т.д. Следуют чрезвычайно различным соглашениям. Для среднего опытного кодера это должно быть намного проще.
Ответы
Ответ 1
- Как насчет
__init__.py
в каталоге Apple... правильно? Пусто или что должно быть внутри?
Да, правильно. Чаще всего пусто. Если вы поместите в него foo = 42
, вы можете позже сделать from apple import foo
, в то время как вам нужно будет сделать from apple.apple import foo
, если вы поместите его в apple.py
. Хотя это может показаться удобным, вы должны использовать его экономно.
- Лучше ли вы называть py.test из корневого каталога? Или тесты py.test?
py.test должен иметь возможность находить ваши тесты независимо, но см. ниже..
- Так много проектов имеют
__init__.py
в своем тестовом каталоге, но это явно указано неверно в документации py.test. Так почему Бог почему
Таким образом, вы можете импортировать файл в тесте, которые предоставляют общие функции тестирования. В py.test, что может быть лучше достигнуто путем создания светильников в файле с именем tests/conftest.py
.
- Что входит в верхнюю часть файла test_everything.py: импортное яблоко или импорт яблока *? или что-то еще полностью
from apple import apple
- Вы называете функции потом eat() или apple.eat()?
apple.eat()
- Некоторые даже рекомендуют манипулировать os.path.dirname в python
Это кажется очень хрупким. Я бы предложил либо
(a) установите переменную окружения PYTHONPATH, чтобы указать на папку, где README.md
, или лучше
(b) создайте файл setup.py(на том же уровне, что и ваш файл README.md
), здесь минимальный:
from setuptools import setup
setup(name='apple', packages=['apple'])
Запустите файл следующим образом:
python setup.py develop
теперь apple
доступен по всему миру, и вы больше никогда не увидите проблему с no module named apple
, то есть вы можете запустить py.test из корневой папки или папки с тестами.
Подробную информацию о setup.py
в руководстве пользователя упаковки Python можно найти в https://python-packaging-user-guide.readthedocs.org/en/latest/index.html
Ответ 2
Я привел пример, который работает здесь.
Я думаю, что это именование как пакета, так и модуля apple
, возможно, это был один из источников путаницы. Единственной неочевидной частью IMO является то, что вы должны установить PYTHONPATH
в текущую директорию, если вы не используете надлежащий пакет setup.py
distutils для установки пакета apple
.