Pregunta 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 framework de pruebas, y espero poder ejecutar py.test tests cuando en el my_project directorio para ejecutar mis pruebas. Esto realmente 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 el directorio que py.test fue ejecutado desde.

Para evitar esto, he agregado un conftest.py archivo a mi tests directorio, 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 aún corriendo 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 el py.test documentación, pero no puedo ver una explicación de este problema o cuál es el enfoque recomendado para enfrentarlo.


32
2018-01-07 12:27


origen


Respuestas:


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, p. pew add . si usa pew, o add2virtualenv . 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 confunden archivos: ponga un vacío conftest.py 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.


31
2018-01-07 13:32



La respuesta es en realidad mucho más fácil, como se ve aquí.

Todo lo que necesitas 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

7
2017-12-22 09:53



La forma más sencilla de hacerlo es, en el directorio de cambio de terminal / cmd, hacia donde está el directorio principal (por ejemplo, en este caso cd C:/.../my_project)

Entonces corre: python -m pytest --cov=mypkg tests

No hay necesidad de meterse con la PYTHONPATH. Al correr con python -m, automáticamente usa esa ruta como PYTHONPATH.


0
2017-08-07 12:05