Asegurar que py.test incluya el directorio de la aplicación en sys.path

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 marco de prueba, y espero poder ejecutar py.test tests cuando my_project en el directorio my_project para ejecutar mis pruebas. Esto realmente funciona, hasta que trato de importar el código de mi aplicación usando (por ejemplo) import mypkg en una prueba. En ese momento, me aparece el error “No hay un 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 el directorio desde donde se ejecutó py.test .

Para conftest.py esto, he agregado un archivo conftest.py a mi 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 manera 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 estructuré mi proyecto?

He visto 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 resolverlo.

Como usted mismo dice, py.test básicamente asume que tiene la configuración de PYTHONPATH correctamente. Hay varias maneras 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 la facilidad de su venv para agregar el directorio de proyectos en sys.path, por ejemplo, pew add . Si usas pew, o add2virtualenv . si usas virtualenv y las extensiones de virtualenvwrapper.

  • Si siempre te gusta el directorio de trabajo actual en sys.path, simplemente puedes exportar PYTHONPATH='' en tu shell. Eso es asegurar la cadena vacía en sys.path que python interpretará como la direcotry de trabajo actual. Sin embargo, esto es potencialmente un peligro para la seguridad.

  • Mi propio truco favorito, abusa de cómo py.test carga archivos conftest: coloca 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 para facilitar la ejecución de las pruebas en un directorio de pruebas / verificación de 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 a su directorio de prueba y cada uno de sus subdirectorios, como tal;

 tests/__init__.py tests/functional/__init__.py tests/unit/__init__.py 

La forma más fácil de hacerlo es, en el directorio / cmd, cambie el directorio a donde está el directorio principal, (por ejemplo, en este caso cd C:/.../my_project ).

Luego ejecute: python -m pytest --cov=mypkg tests

No hay necesidad de meterse con la variable de entorno PYTHONPATH . Al ejecutarse con python -m pytest , agrega automáticamente el directorio actual a sys.path .