modulos - Python importa para pruebas usando nariz: ¿cuál es la mejor práctica para las importaciones de módulos por encima del paquete actual?
modulos python (3)
Esta es una pregunta que se realiza con frecuencia en diferentes formas, y a menudo obtiene respuestas de "ja, ja no lo está haciendo correctamente". Estoy bastante seguro de que es porque hay un escenario de sentido común que las personas (incluyéndome a mí) están tratando de usar como una implementación, y la solución no es obvia (si no lo has hecho antes).
Aceptaría una respuesta que "deja volar de la botella".
Dado
project/
__init__.py
/code
__init__.py
sut.py
/tests
__init__.py
test_sut.py
Donde tests_sut.py comienza:
import code.sut
Ejecutar nosetests en el directorio raíz lleva a:
ImportError: No module named code.sut
Avenidas recorridas
a) hacer un familiar usando
from ..code import sut
b) agregar la raíz del proyecto a PYTHONPATH
c) usar el
sys.path.append
para agregar la ruta ... antes de las importaciones al comienzo de cada módulo de prueba.
d) solo recuerda hacer un
setup.py
en el proyecto para instalar los módulos en los paquetes de sitio antes de ejecutar las pruebas.
Por lo tanto, el requisito es tener pruebas ubicadas debajo de la raíz del paquete de prueba que tengan acceso al proyecto. ¡Cada uno de los anteriores no me parece "natural", me ha resultado problemático o me parece que es demasiado trabajo!
En Java esto funciona, pero básicamente a fuerza de su herramienta de compilación / IDE colocando todas sus clases en el classpath. Tal vez el problema es que estoy esperando "magia" de Python? Haber observado en las pruebas de Flab webframework, la opción d) parece ser la preferida.
En cualquier caso, las declaraciones a continuación que recomiendan una solución preferida eliminarían la sensación de "falta de naturalidad" en la mía.
Sé que hay una respuesta marcada y todavía creo que es una buena razón para compartir otras alternativas :)
Hay una nose-pathmunge da un control para establecer sys.path
al invocar nosestests
.
Tuve el mismo problema y encontré una answer para mí en una pregunta relacionada.
Simplemente elimine __init__.py en la raíz del proyecto.
Ya ha respondido a su pregunta bastante bien ... D (instalar en la ubicación del sistema) es preferible para el código distribuible. Usualmente uso C (modifico sys.path) porque no quiero instalar todo el sistema de mis cientos de libs personalizadas. En teoría, A (importación relativa) parece más agradable, pero hay casos en los que falla. B (PYTHONPATH) está bien, realmente solo para fines de prueba, en mi opinión.
Eso resume prácticamente todas las opciones. La opción que prefiera (Python sabe mágicamente dónde buscar) realmente no es una solución factible porque puede generar resultados impredecibles, como la búsqueda automática de bibliotecas de proyectos no relacionados.
En mi opinión, lo mejor que puede hacer es poner esto en el (los) punto (s) de entrada a su programa:
import sys, os
sys.path = [os.path.abspath(os.path.dirname(__file__))] + sys.path