Error de importación de Python Nose

121

Parece que no puedo hacer que el marco de prueba de nariz reconozca los módulos debajo de mi script de prueba en la estructura de archivos. He creado el ejemplo más simple que demuestra el problema. Te lo explicaré a continuación.

Aquí está la estructura del archivo del paquete:

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

foo.py contiene:

def dumb_true():
    return True

tests / test_foo.py contiene:

import foo

def test_foo():
    assert foo.dumb_true()

Ambos archivos init .py están vacíos

Si ejecuto nosetests -vven el directorio principal (donde está foo.py), obtengo:

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)

Recibo el mismo error cuando ejecuto desde dentro del directorio tests /. De acuerdo con la documentación y un ejemplo que encontré, se supone que nose debe agregar todos los paquetes principales a la ruta, así como el directorio desde el que se llama, pero esto no parece estar sucediendo en mi caso.

Estoy ejecutando Ubuntu 8.04 con Python 2.6.2. He construido e instalado la nariz manualmente (no con setup_tools) si eso importa.

halfak
fuente

Respuestas:

226

Tienes un __init__.pyen tu directorio de nivel superior. Eso lo convierte en un paquete. Si lo quita, nosetestsdebería funcionar.

Si no lo elimina, tendrá que cambiar su importa import dir.foo, donde direstá el nombre de su directorio.

ire_and_curses
fuente
7
Eso lo consiguió. ¡Muchas gracias! Yo votaría, pero aparentemente necesito más reputación.
halfak
4
Sin preocupaciones. ¡Bienvenido a StackOverflow! Puede marcar la marca de verificación verde a la izquierda si la respuesta resuelve su problema.
ire_and_curses
2
@halfak: Entonces, tenga otro voto positivo sobre su pregunta. Tú también (en tu respuesta), @ire.
Mark Rushakoff
1
Entendido. Gracias por el consejo :)
halfak
5
Tengo una situación en la que las pruebas funcionan si init .py en el directorio raíz; sin embargo, necesito que ese archivo esté allí y los modelos de importación. <model_name> aún no se encuentra. La prueba está dentro de un directorio tests / , y el modelo que estoy tratando de probar está dentro del directorio modelos / ... se agradecería cualquier ayuda.
Kees Briggs
32

¿Estás en un virtualenv? En mi caso, nosetestsfue el /usr/bin/nosetestsque estaba usando /usr/bin/python. Los paquetes del virtualenv definitivamente no estarán en la ruta del sistema. Lo siguiente solucionó esto:

source myvirtualenv/activate
pip install nose
which nosetests
/home/me/myvirtualenv/bin/nosetests
toppur
fuente
2
También mío. Gracias, ahorré mucho tiempo.
jskulski
3
para mí nosetestsfue almacenado en caché por bashel sistema uno en /usr/local/bin(mientras which nosetestsdaba el resultado adecuado). Usé esto para borrarlo.
Raffi
5
Además, tuve que desactivar y activar mi virtualenv.
Bengt
Tuve un problema con PS1 = $ {PS1: -} establecido al activar virtualenv (para superar errores en variables no configuradas). Después de eliminar esto y cambiar a set + u , ya no tuve problemas.
Juuso Ohtonen
13

Para aquellos de ustedes que encuentren esta pregunta más adelante: Recibo el error de importación si no tengo un __init__.pyarchivo en mi directorio de pruebas.

Mi estructura de directorio era así:

./tests/
  ./test_some_random_stuff.py

Si hice pruebas de nariz:

nosetests -w tests

Daría lo ImportErrorque todos los demás están viendo. Si agrego un __init__.pyarchivo en blanco , funciona bien:

./tests/
  ./__init__.py
  ./test_some_random_stuff.py
robbrit
fuente
10

Otro problema potencial parecen ser los guiones / guiones en el árbol de directorios. Recientemente solucioné un problema de ImportError de nariz al cambiar el nombre de un directorio de sub-dira sub_dir.

Aron Ahmadia
fuente
1
@Aman, ¿te das cuenta de la diferencia entre identificadores de variables y nombres de archivos?
Nakilon
Sí ... Siempre tengo un archivo que era similar a FooTests.py y por alguna razón no le gustó ... Cambié el nombre a Foo_Tests.py y funcionó ... parece un poco delicado.
Birdman
3

Por supuesto, si tiene un error de sintaxis en el módulo que se está importando, esto lo causará. Para mí, el problema surgió cuando tuve una copia de seguridad de un archivo de pruebas con una ruta como module / tests.bak.py en el mismo directorio que tests.py. Además, para solucionar el problema del módulo / paquete init en una aplicación Django, puede ejecutar lo siguiente (en un shell bash / OSX) para asegurarse de que no tiene ningún archivo init .pyc por ahí:

find . -name '*.pyc' -delete
encimeras
fuente
3

Recibí este mensaje de error porque ejecuté el nosetestscomando desde el directorio incorrecto.

Tonto, pero pasa.

Eyal Levin
fuente
¿Puede agregar algunos detalles a su respuesta? ¿Desde qué directorio lo ejecutó? ¿Por qué está mal? ¿Cuál sería el directorio correcto? Ejecutar nosetestsen un directorio sin ninguna prueba resultará en Ran 0 testsningún error de importación. En su forma actual, esta respuesta no es útil.
gerrit
2

Me encontré con una cosa más que podría causar este problema: nombrar las pruebas en el formulario testname.test.py. Ese extra .confunde la nariz y la lleva a importar cosas que no debería. Supongo que puede ser obvio que usar convenciones de nomenclatura de prueba no convencionales romperá las cosas, pero pensé que valdría la pena señalarlo.

7yl4r
fuente
2

Por ejemplo, con la siguiente estructura de directorios, si se desea ejecutar nosetestsen m1, m2o m3para probar algunas funciones en n.py, usted debe utilizar from m2.m3 import nen test.py.

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

Solo para completar la pregunta: si está luchando con una estructura como esta:

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

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

Y tal vez desee ejecutar la prueba desde una ruta fuera del proyecto, incluya la ruta de su proyecto dentro de su PYTHONPATH.

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

péguelo dentro de su .profile. Si se encuentra en un entorno virtual, péguelo dentro de la activación en su raíz de venv

Rainelz
fuente