325 votes

Problème de PATH avec pytest 'ImportError : Pas de module nommé YadaYadaYada'.

J'ai utilisé easy_install pour installer pytest sur un mac et j'ai commencé à écrire des tests pour un projet avec une structure de fichiers comme celle-ci :

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

exécuter py.test alors que dans le répertoire repo, tout se comporte comme on peut s'y attendre

mais quand j'essaie la même chose sous linux ou Windows (les deux ont pytest 2.2.3 sur eux), il aboie dès qu'il rencontre sa première importation de quelque chose de mon chemin d'application. Disons par exemple from app import some_def_in_app

Dois-je modifier mon PATH pour exécuter py.test sur ces systèmes ? Quelqu'un a-t-il déjà rencontré ce problème ?

393voto

Apteryx Points 4279

Je ne sais pas pourquoi py.test n'ajoute pas le répertoire courant dans le PYTHONPATH lui-même, mais voici une solution de contournement (à exécuter depuis la racine de votre dépôt) :

python -m pytest tests/

Cela fonctionne parce que Python ajoute le répertoire courant dans le PYTHONPATH pour vous.

295voto

hoefling Points 10709

Approche recommandée pour pytest>=7 : utiliser le pythonpath paramètre

Récemment, pytest a ajouté un nouveau plugin de base qui prend en charge sys.path modifications via le pythonpath valeur de configuration . La solution est donc beaucoup plus simple maintenant et ne nécessite plus aucune solution de contournement :

pyproject.toml exemple :

[tool.pytest.ini_options]
pythonpath = [
  "."
]

pytest.ini exemple :

[pytest]
pythonpath = .

Les entrées de chemin sont calculées par rapport au répertoire racine, ainsi . ajoute repo pour sys.path dans ce cas.

Les entrées de chemins multiples sont également autorisées : pour une disposition

repo/
 src/
|    lib.py
 app.py
 tests
      test_app.py
      test_lib.py

la configuration

[tool.pytest.ini_options]
pythonpath = [
  ".", "src",
]

ou

[pytest]
pythonpath = . src

ajoutera à la fois app et lib modules pour sys.path donc

import app
import lib

fonctionneront tous les deux.

Réponse originale (non recommandée pour les versions récentes de pytest ; à utiliser pour pytest<7 uniquement) : conftest solution

La solution la moins invasive consiste à ajouter un fichier vide nommé conftest.py dans le repo/ répertoire :

$ touch repo/conftest.py

C'est tout. Il n'est pas nécessaire d'écrire du code personnalisé pour manipuler les fichiers sys.path ou n'oubliez pas de faire glisser PYTHONPATH le long, ou en plaçant __init__.py dans des répertoires où il n'a pas sa place (en utilisant python -m pytest comme suggéré dans Apteryx 's réponse est une bonne solution cependant !).

Le répertoire du projet après :

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

Explication

pytest cherche le conftest sur la collection de tests afin de rassembler les hooks et fixtures personnalisés, et afin d'importer les objets personnalisés à partir de ceux-ci, pytest ajoute le répertoire parent du conftest.py à la sys.path (dans ce cas, le repo ).

Autres structures de projet

Si vous avez une autre structure de projet, placez le conftest.py dans le répertoire racine du paquet (celui qui contient les paquets mais qui n'est pas un paquet lui-même, donc pas de no contiennent un __init__.py ), par exemple :

repo
 conftest.py
 spam
    __init__.py
    bacon.py
    egg.py
 eggs
    __init__.py
    sausage.py
 tests
      test_bacon.py
      test_egg.py

src mise en page

Bien que cette approche puisse être utilisée avec le src disposition (place conftest.py dans le src dir) :

repo
 src
    conftest.py
    spam
       __init__.py
       bacon.py
       egg.py
    eggs 
        __init__.py
        sausage.py
 tests
      test_bacon.py
      test_egg.py

Attention, l'ajout de src a PYTHONPATH atténue la signification et les avantages de la src mise en page ! Vous finirez par tester le code du référentiel et non le paquet installé. Si vous avez besoin de le faire, peut-être n'avez-vous pas besoin de l'option src dir du tout.

Où aller à partir de maintenant

Bien sûr, conftest ne sont pas seulement quelques fichiers pour faciliter la découverte du code source ; c'est là que se trouvent toutes les améliorations spécifiques au projet de l'application pytest et la personnalisation de votre suite de tests. pytest a beaucoup d'informations sur conftest modules dispersés dans leurs docs ; commencer par conftest.py : plugins locaux par répertoire

Aussi, SO a une excellente question sur conftest modules : Dans py.test, quelle est l'utilité des fichiers conftest.py ?

136voto

Aron Curzon Points 574

J'ai eu le même problème. Je l'ai résolu en ajoutant un __init__.py à mon tests répertoire.

127voto

Not_a_Golfer Points 8585

Oui, le dossier source n'est pas dans le chemin de Python si vous cd dans le répertoire des tests.

Vous avez deux choix :

  1. Ajoutez le chemin manuellement aux fichiers de test, quelque chose comme ceci :

    import sys, os
    myPath = os.path.dirname(os.path.abspath(__file__))
    sys.path.insert(0, myPath + '/../')
  2. Exécuter les tests avec la var env PYTHONPATH=../ .

56voto

Stefano Messina Points 1353

Exécuter pytest en tant que module avec : python -m pytest tests

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X