Erreur d'importation de nez Python

121

Je n'arrive pas à faire en sorte que le framework de test du nez reconnaisse les modules sous mon script de test dans la structure de fichiers. J'ai mis en place l'exemple le plus simple qui illustre le problème. Je vais l'expliquer ci-dessous.

Voici la structure du fichier du package:

./__init__.py
./foo.py
./tests
   ./__init__.py
   ./test_foo.py

foo.py contient:

def dumb_true():
    return True

tests / test_foo.py contient:

import foo

def test_foo():
    assert foo.dumb_true()

Les deux fichiers init .py sont vides

Si je cours nosetests -vvdans le répertoire principal (où se trouve foo.py), j'obtiens:

Failure: ImportError (No module named foo) ... ERROR

======================================================================
ERROR: Failure: ImportError (No module named foo)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/usr/lib/python/site-packages/nose-0.11.1-py2.6.egg/nose/loader.py", line 379, in loadTestsFromName
    addr.filename, addr.module)
  File "/usr/lib/python/site-packages/nose-0.11.1-py2.6.egg/nose/importer.py", line 39, in importFromPath
    return self.importFromDir(dir_path, fqname)
  File "/usr/lib/python/site-packages/nose-0.11.1-py2.6.egg/nose/importer.py", line 86, in importFromDir
    mod = load_module(part_fqname, fh, filename, desc)
  File "/home/user/nose_testing/tests/test_foo.py", line 1, in <module>
    import foo
ImportError: No module named foo

----------------------------------------------------------------------
Ran 1 test in 0.002s

FAILED (errors=1)

J'obtiens la même erreur lorsque je cours depuis le répertoire tests /. D'après la documentation et un exemple que j'ai trouvé, nose est censé ajouter tous les packages parents au chemin ainsi que le répertoire à partir duquel il est appelé, mais cela ne semble pas se produire dans mon cas.

J'utilise Ubuntu 8.04 avec Python 2.6.2. J'ai construit et installé le nez manuellement (pas avec setup_tools) si cela compte.

Halfak
la source

Réponses:

226

Vous avez un __init__.pydans votre répertoire de niveau supérieur. Cela en fait un paquet. Si vous le supprimez, votre nosetestsdevrait fonctionner.

Si vous ne le supprimez pas, vous devrez changer votre importen import dir.foo, où direst le nom de votre répertoire.

ire_and_curses
la source
7
Cela l'a compris. Merci beaucoup! Je voterais, mais apparemment j'ai besoin de plus de réputation.
halfak
4
Pas de soucis. Bienvenue dans StackOverflow! Vous pouvez cocher la coche verte à gauche si la réponse résout votre problème.
ire_and_curses
2
@halfak: Ayez un autre vote pour votre question alors. Vous aussi (sur votre réponse), @ire.
Mark Rushakoff
1
Je l'ai. Merci pour le tuyau :)
halfak
5
J'ai une situation où les tests fonctionnent si init .py dans le répertoire racine - cependant, j'ai besoin que ce fichier soit là et que j'importe des modèles. <model_name> n'est toujours pas trouvé. Le test se trouve dans un répertoire tests / , et le modèle que j'essaie de tester est dans le répertoire models / ... toute aide serait appréciée.
Kees Briggs
32

Êtes-vous dans une virtualenv? Dans mon cas, nosetestsc'était celui /usr/bin/nosetestsqui utilisait /usr/bin/python. Les packages de virtualenv ne seront certainement pas dans le chemin du système. Ce qui suit a corrigé ce problème:

source myvirtualenv/activate
pip install nose
which nosetests
/home/me/myvirtualenv/bin/nosetests
toppur
la source
2
Aussi le mien. Merci, gagné beaucoup de temps.
jskulski
3
pour moi a nosetestsété mis en cache par bashle système one in /usr/local/bin(tout en which nosetestsdonnant le résultat approprié). Je cela pour l' effacer.
Raffi
5
De plus, j'ai dû désactiver et activer mon virtualenv.
Bengt le
J'ai eu un problème avec PS1 = $ {PS1: -} défini lors de l'activation de virtualenv (pour surmonter les erreurs sur les variables non définies). Après avoir supprimé cela et basculé sur set + u , je n'ai plus eu de problèmes.
Juuso Ohtonen
13

À ceux d'entre vous qui trouveront cette question plus tard: j'obtiens l'erreur d'importation si je n'ai pas de __init__.pyfichier dans mon répertoire de tests.

Ma structure de répertoires était comme ceci:

./tests/
  ./test_some_random_stuff.py

Si j'ai effectué nos tests:

nosetests -w tests

Cela donnerait ce ImportErrorque tout le monde voit. Si j'ajoute un __init__.pyfichier vierge , cela fonctionne très bien:

./tests/
  ./__init__.py
  ./test_some_random_stuff.py
Robbrit
la source
10

Un autre problème potentiel semble être les traits d'union / tirets dans l'arborescence des répertoires. J'ai récemment corrigé un problème d'ImportError de nez en renommant un répertoire de sub-dirà sub_dir.

Aron Ahmadia
la source
1
@Aman, vous réalisez la différence entre les identificateurs de variables et les noms de fichiers?
Nakilon le
Ouais ... J'ai toujours un fichier qui était similaire à FooTests.py et pour une raison quelconque, il ne l'aimait pas ... J'ai renommé Foo_Tests.py et cela a fonctionné ... semble un peu capricieux.
Birdman
3

Bien sûr, si vous avez une erreur de syntaxe dans le module importé, cela en sera la cause. Pour moi, le problème a surgi lorsque j'ai eu une sauvegarde d'un fichier de tests avec un chemin comme module / tests.bak.py dans le même répertoire que tests.py. De plus, pour résoudre le problème du package / module init dans une application Django, vous pouvez exécuter ce qui suit (dans un shell bash / OSX) pour vous assurer que vous n'avez pas de fichiers init .pyc qui traînent:

find . -name '*.pyc' -delete
plaques de cuisson
la source
3

J'ai reçu ce message d'erreur car j'exécute la nosetestscommande à partir du mauvais répertoire.

C'est idiot, mais ça arrive.

Eyal Levin
la source
Pouvez-vous s'il vous plaît ajouter quelques détails à votre réponse? Dans quel répertoire l'avez-vous exécuté? Pourquoi est-ce mal? Quel serait le bon répertoire? L'exécution nosetestsdans un répertoire sans test du tout entraînera Ran 0 testsune erreur d'importation. Dans sa forme actuelle, cette réponse n'est pas utile.
gerrit
2

Je viens de rencontrer une dernière chose qui pourrait causer ce problème: la dénomination des tests dans le formulaire testname.test.py. Ce supplément .confond le nez et le conduit à importer des choses qu'il ne devrait pas. Je suppose qu'il peut être évident que l'utilisation de conventions de dénomination de test non conventionnelles brisera les choses, mais j'ai pensé que cela mériterait d'être noté.

7yl4r
la source
2

Par exemple, avec la structure de répertoire suivant, si vous voulez exécuter nosetestsdans m1, m2ou m3pour tester certaines fonctions n.py, vous devez utiliser from m2.m3 import ndans test.py.

m1
└── m2
    ├── __init__.py
    └── m3
        ├── __init__.py
        ├── n.py
        └── test
            └── test.py
Che-Hsun Liu
la source
1

Juste pour compléter la question: si vous avez du mal avec une structure comme celle-ci:

project
├── m1
    ├── __init__.py
    ├── foo1.py
    └──m2
       ├── __init__.py
       └── foo2.py

└── test
     ├── __init__.py
     └── test.py

Et peut-être souhaitez-vous exécuter un test à partir d'un chemin en dehors du projet, incluez le chemin de votre projet dans votre PYTHONPATH.

export PYTHONPATH=$PYTHONPATH:$HOME/path/to/project

collez-le dans votre .profile. Si vous êtes dans un environnement virtuel, collez-le dans le activate de votre racine venv

Rainelz
la source