64 votes

Importations Python pour des tests utilisant nose - Quelle est la meilleure pratique pour importer des modules supérieurs au package actuel

C'est une question qui est fréquemment demandé dans différentes formes, et souvent obtient "lol, vous ne le font pas correctement" les réponses. Assez sûr que c'est parce qu'il y a un sens commun scénario de gens (dont moi) sont en train de l'utiliser comme une mise en œuvre, et la solution n'est pas évidente (si vous ne l'avez pas fait avant).

Serait accepter une réponse "vous permet de la sortir de la bouteille".

Compte tenu de

project/
    __init__.py
    /code
        __init__.py
        sut.py
    /tests
        __init__.py
        test_sut.py

Où tests_sut.py commence:

import code.sut

L'exécution de nosetests dans le répertoire racine conduit à:

ImportError: No module named code.sut

Avenues voyagé:

a) faire un par rapport à l'aide de

from ..code import sut

b) ajouter la racine du projet de PYTHONPATH

c) utiliser le

sys.path.append

pour ajouter le chemin .. avant que les importations au début de chaque module de test.

d) n'oubliez pas de faire un

setup.py 

sur le projet d'installer les modules dans le site-packages avant l'exécution des tests.


Ainsi, l'exigence est d'avoir des tests situé sous le package de test de racine qui ont accès au projet. Chacun des ci-dessus ne se sentent pas "naturel" pour moi, se sont avérés problématiques ou sembler trop dur travail!

En java, cela fonctionne, mais, fondamentalement, par la force de votre outil de construction / IDE de placer tous vos classes sur le chemin de la classe. Peut-être le problème est que j'attends "magie" de Python? L'avons noté dans le Flacon webframework tests, l'option d) semble être préféré.

Dans tous les cas, les déclarations ci-dessous recommander une solution serait de supprimer la sensation de "unnaturalness" dans mon propre.

44voto

cnu Points 6802

J'ai eu le même problème et j'ai trouvé une réponse dans une question connexe qui fonctionne pour moi.

Supprimez simplement __init__.py dans la racine du projet.

11voto

Luke Points 4250

Vous avez répondu à votre question assez bien déjà.. D (à installer à l'emplacement du système) est préféré du code distribuable. Habituellement, j'utilise des C (modifier sys.chemin d'accès) parce que je ne veux pas à l'échelle du système installe de mes des centaines de libs. En théorie, Une (relative à l'importation) semble plus agréable, mais il y a des cas où il échoue. B (PYTHONPATH) est juste, vraiment fins de test uniquement, à mon avis.

Cela résume assez bien l'ensemble des options. L'option que vous préférez (Python comme par magie sait où chercher), c'est vraiment pas une solution viable car il peut conduire à des résultats imprévisibles, comme magiquement à trouver les bibliothèques de projets indépendants.

À mon avis, la meilleure chose à faire est de mettre cela au point d'entrée(s) à votre programme:

import sys, os
sys.path = [os.path.abspath(os.path.dirname(__file__))] + sys.path

4voto

Drake Points 2306

Je sais qu'il y a une réponse vérifiée et je pense toujours que c'est une bonne raison de partager d'autres alternatives :)

Un nez-pathmunge vous donne le contrôle de définir sys.path tout en appelant nosestests .

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