Структура каталога проекта 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. Хотя это может показаться удобным, вы должны использовать его экономно.

  1. Лучше ли вы называть py.test из корневого каталога? Или тесты py.test?

py.test должен иметь возможность находить ваши тесты независимо, но см. ниже..

  1. Так много проектов имеют __init__.py в своем тестовом каталоге, но это явно указано неверно в документации py.test. Так почему Бог почему

Таким образом, вы можете импортировать файл в тесте, которые предоставляют общие функции тестирования. В py.test, что может быть лучше достигнуто путем создания светильников в файле с именем tests/conftest.py.

  1. Что входит в верхнюю часть файла test_everything.py: импортное яблоко или импорт яблока *? или что-то еще полностью

from apple import apple

  1. Вы называете функции потом eat() или apple.eat()?

apple.eat()

  1. Некоторые даже рекомендуют манипулировать 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.