python - Asegurar que py.test incluya el directorio de la aplicación en sys.path
unit-testing (2)
Tengo una estructura de directorio de proyectos de la siguiente manera (que creo que es bastante estándar):
my_project
setup.py
mypkg
__init__.py
foo.py
tests
functional
test_f1.py
unit
test_u1.py
Estoy usando py.test para mi framework de pruebas, y espero poder ejecutar py.test tests
cuando my_project
en el directorio my_project
para ejecutar mis pruebas. De hecho, esto funciona, hasta que intento importar el código de mi aplicación usando (por ejemplo) import mypkg
en una prueba. En ese momento, aparece el error "Ningún módulo llamado mypkg". Al hacer un poco de investigación, parece que py.test
ejecuta las pruebas con el directorio del archivo de prueba en sys.path
, pero no en el directorio desde el que se ejecutó py.test
.
Para conftest.py
este problema, he agregado un archivo conftest.py
al directorio de tests
, que contiene el siguiente código:
import sys, os
# Make sure that the application source directory (this directory''s parent) is
# on sys.path.
here = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
sys.path.insert(0, here)
Esto parece funcionar, pero ¿es una buena forma de asegurarse de que las pruebas vean el código de la aplicación? ¿Hay una mejor manera de lograr esto o estoy haciendo algo mal en la forma en que tengo mi proyecto estructurado?
He visto algunos otros proyectos que usan py.test
(por ejemplo, pip
) pero no puedo ver el código que hace algo como esto, y sin embargo, la ejecución de py.test tests
parece funcionar allí. No sé muy bien por qué, pero me preocupa que puedan haber logrado el mismo resultado de una manera más simple.
He buscado en la documentación de py.test
, pero no puedo ver una explicación de este problema o cuál es el enfoque recomendado para tratarlo.
Como dices tú mismo, py.test básicamente asume que tienes la configuración PYTHONPATH configurada correctamente. Hay varias formas de lograr esto:
Dale a tu proyecto un setup.py y usa
pip install -e .
en un virtualenv para este proyecto. Este es probablemente el método estándar.Como una variación de esto, si tiene un virtualenv pero no setup.py use las instalaciones de su venv para agregar el directorio de proyectos en sys.path, pe
pew add .
si usa pew, oadd2virtualenv .
si usas virtualenv y las extensiones de virtualenvwrapper.Si siempre te gusta el directorio de trabajo actual en sys.path, siempre puedes exportar
PYTHONPATH=''''
en tu caparazón. Eso es asegurar que la cadena vacía esté activada en sys.path, lo que python interpretará como el directorio actual de trabajo. Sin embargo, esto es potencialmente un peligro para la seguridad.Mi propio hack favorito, abuse de cómo las cargas py.test confieren archivos: coloque un
conftest.py
vacío en el directorio de nivel superior del proyecto.
La razón por la cual py.test se comporta de esta manera es hacer que sea más fácil ejecutar las pruebas en un directorio de tests / de un pago contra un paquete instalado. Si añadiera incondicionalmente el directorio del proyecto a PYTHONPATH, esto ya no sería posible.
La respuesta es en realidad mucho más fácil, como se ve aquí .
Todo lo que necesita hacer es agregar un __init__.py
al directorio de prueba y a cada uno de sus subdirectorios, como tal;
tests/__init__.py
tests/functional/__init__.py
tests/unit/__init__.py