web-dev-qa-db-fra.com

Importations relatives avec unittest dans Python

J'essaie d'utiliser Python les importations les plus unitaires et relatives, et je n'arrive pas à le comprendre. Je sais qu'il y a beaucoup de questions connexes, mais aucune n'a aidé jusqu'à présent. Désolé si c'est répétitif, mais j'apprécierais vraiment toute aide. J'essayais d'utiliser la syntaxe de PEP 328 http://www.python.org/dev/peps/pep-0328/ mais Je dois avoir quelque chose de mal.

Ma structure de répertoire est:

project/
    __init__.py
    main_program.py
    lib/
        __init__.py
        lib_a
        lib_b
    tests/
        __init__.py
        test_a
        test_b

Je lance mes tests en utilisant:

python -m unittest test_module1 test_module2

test_a doit importer à la fois lib/lib_a et main_program. Voici le code de test_a que j'essaie d'utiliser pour l'importation:

from ..lib import lib_a as lib
from ...project import main_program

les deux soulèvent cette erreur:

ValueError: Attempted relative import in non-package

Tous mes fichiers init . Py sont actuellement vides.

Tout conseil spécifique serait grandement apprécié !!

Éditer:

Cela peut être la réponse: Paquets Python? Je vérifie toujours si cela fonctionnera.

Edit II:

Pour clarifier, à ce stade, j'ai tenté d'exécuter mon fichier de test de 3 manières différentes:

project/tests $ python -m unittest test_a
project/tests $ python -m test_a
project/tests $ ./test_a

Les trois échouent avec la même erreur que ci-dessus. Lorsque j'utilise les mêmes trois syntaxes mais dans le répertoire du projet, j'obtiens cette erreur:

ValueError: Attempted relative import beyond toplevel package

Merci encore.

35
J Jones

D'après mon expérience, il est plus facile si la racine de votre projet n'est pas un package, comme ceci:

project/
  test.py
  run.py
  package/
    __init__.py
    main_program.py
    lib/
      __init__.py
      lib_a
      lib_b
    tests/
      __init__.py
      test_a
      test_b

Cependant, à partir de python 3.2, le module unittest fournit le -t option, qui vous permet de définir le répertoire de niveau supérieur, afin que vous puissiez faire (à partir de package/):

python -m unittest discover -t ..

Plus de détails sur le dittest docs .

19
kai

Je cours avec le même problème et la réponse de kai l'a résolu. Je veux juste compléter sa réponse avec le contenu de test.py(comme @gsanta l'a demandé). Je ne l'ai testé que sur Python 2.7:

from packages.tests import test_a, test_b
import unittest

# for test_a
unittest.main(test_a)

# for test_b
unittest.main(test_a)

alors vous pouvez juste

../project $ python test.py
2

Dans une mise en page où les tests et les packages sont au niveau frère:

/project
   /tests
   /package

Une façon consiste à commencer dans le package dir, utilisez - s pour découvrir uniquement dans teste , et utilise - t pour définir le niveau supérieur:

../package $ python3 -m unittest discover -s ../tests -t ..

0
Eric Jarvi