web-dev-qa-db-fra.com

Python structure du répertoire du projet / problème pytest

Cela devrait être le problème le plus simple au monde, mais même après de longues recherches et bricolages, je suis toujours en grande difficulté à trouver un moyen "correct" de créer une structure de répertoires et de gérer correctement pytest, etc.

Disons que j'ai un programme appelé Apple.

|- README.md
|- Apple
|   |-- __init__.py
|   |-- Apple.py
| - tests
|   |-- test_everything.py

Le Apple.py contient quelques fonctions, par exemple, appelons un eat(). Et le fichier test_everything.py Contient des tests comme assert eat()=="foobar". Si bon si facile, mais le plaisir commence:

  • Qu'en est-il du __init__.py Dans le Apple ... correct? Vide ou que doit-il contenir?
  • Est-il recommandé d'appeler py.test À partir du répertoire racine? Ou py.test tests?
  • De nombreux projets ont un __init__.py Dans leur répertoire de test, mais cela est explicitement dit faux dans la documentation py.test. Alors pourquoi Dieu pourquoi
  • Qu'est-ce qui se trouve en haut du fichier test_everything.py: Un import Apple Ou from Apple import *? ou autre chose
  • Appelez-vous ensuite les fonctions par eat() ou Apple.eat()?
  • Certains recommandent même de manipuler os.path.dirname En python

Cela devrait être facile, mais j'ai vu toutes les combinaisons de ce qui précède, sans même parler de tox et de la myriade d'autres outils. Pourtant, avec la moindre erreur, vous obtenez un ImportError: No module named 'Apple' Ou une autre erreur géniale.

Quelle est la bonne façon? Les conseils et le code existant sur github etc. suivent des conventions extrêmement différentes. Pour un codeur moyennement expérimenté, cela devrait être beaucoup plus facile.

37
Basti
  1. Qu'en est-il du __init__.py Dans le Apple ... correct? Vide ou que doit-il contenir?

Oui correct. Le plus souvent vide. Si vous y mettez foo = 42, Vous pourrez plus tard from Apple import foo Pendant que vous devrez faire from Apple.apple import foo Si vous le mettez dans Apple.py. Bien que cela puisse sembler pratique, vous devez l'utiliser avec parcimonie.

  1. Est-il recommandé d'appeler py.test à partir du répertoire racine? Ou des tests py.test?

py.test devrait être en mesure de trouver vos tests malgré tout, mais voir ci-dessous ..

  1. De nombreux projets ont un __init__.py Dans leur répertoire de test, mais cela est explicitement dit faux dans la documentation py.test. Alors pourquoi Dieu pourquoi

Vous pouvez donc importer un fichier dans des tests qui fournissent des fonctionnalités de test communes. Dans py.test, cela pourrait être mieux réalisé en créant des fixtures dans un fichier appelé tests/conftest.py.

  1. Ce qui vient en haut du fichier test_everything.py: une importation Apple ou de Apple importation *? Ou autre chose entièrement)

from Apple import Apple

  1. Appelez-vous ensuite les fonctions par eat () ou Apple.eat ()?

Apple.eat()

  1. Certains recommandent même de manipuler os.path.dirname en python

Cela semble très fragile. Je suggérerais soit

(a) définissez la variable d'environnement PYTHONPATH pour pointer vers le dossier où README.md est, ou mieux

(b) créez un fichier setup.py (au même niveau que votre fichier README.md), en voici un minimal:

from setuptools import setup
setup(name='Apple', packages=['Apple'])

Exécutez le fichier comme ceci:

python setup.py develop

maintenant Apple est globalement disponible et vous ne devriez plus jamais voir un problème no module named Apple, c'est-à-dire que vous pouvez exécuter py.test à partir du dossier racine ou du dossier tests.

Vous pouvez en savoir plus sur setup.py Dans le Python Packaging User Guide at https://python-packaging-user-guide.readthedocs.org/en/latest /index.html

20
thebjorn

J'ai arrangé un exemple qui fonctionne ici .

Je pense que nommer les modules et du module Apple confus , c'était peut-être une source de confusion. La seule partie non évidente de l'OMI est que vous devez définir PYTHONPATH sur le répertoire courant si vous n'utilisez pas un setup.py package distutils pour installer votre package Apple.

4
Bruno Oliveira