La estructura de directorio muy común, incluso para un módulo Python simple, parece ser separar las pruebas unitarias en su propio test
directorio:
new_project/
antigravity/
antigravity.py
test/
test_antigravity.py
setup.py
etc.
por ejemplo, vea este tutorial sobre proyectos de Python .
Mi pregunta es simplemente ¿Cuál es la forma habitual de ejecutar realmente las pruebas? Sospecho que esto es obvio para todos, excepto para mí, pero no puede simplemente ejecutar python test_antigravity.py
desde el directorio de prueba ya import antigravity
que fallará ya que el módulo no está en la ruta.
Sé que podría modificar PYTHONPATH y otros trucos relacionados con la ruta de búsqueda, pero no puedo creer que sea la forma más simple: está bien si usted es el desarrollador, pero no es realista esperar que sus usuarios lo usen si solo quieren verificar si las pruebas son paso.
La otra alternativa es simplemente copiar el archivo de prueba en el otro directorio, pero parece un poco tonto y pierde el punto de tenerlos en un directorio separado para comenzar.
Entonces, si acabara de descargar la fuente a mi nuevo proyecto, ¿cómo ejecutaría las pruebas unitarias? Prefiero una respuesta que me permita decirles a mis usuarios: "Para ejecutar las pruebas unitarias, haga X".
fuente
unittest
interfaz de línea de comandos como se describe en mi respuesta a continuación para que no tenga que agregar el directorio a la ruta.Respuestas:
La mejor solución en mi opinión es usar la
unittest
interfaz de línea de comando que agregará el directorio alsys.path
para que no tenga que hacerlo (hecho en laTestLoader
clase).Por ejemplo, para una estructura de directorios como esta:
Solo puedes ejecutar:
Para una estructura de directorio como la suya:
Y en los módulos de prueba dentro del
test
paquete, puede importar elantigravity
paquete y sus módulos como de costumbre:Ejecutando un solo módulo de prueba:
Para ejecutar un solo módulo de prueba, en este caso
test_antigravity.py
:Simplemente haga referencia al módulo de prueba de la misma manera que lo importa.
Ejecutar un único caso de prueba o método de prueba:
También puede ejecutar un
TestCase
método de prueba único o único:Ejecutando todas las pruebas:
También puede usar el descubrimiento de pruebas, que descubrirá y ejecutará todas las pruebas por usted, deben ser módulos o paquetes nombrados
test*.py
(se pueden cambiar con el-p, --pattern
indicador):Esto ejecutará todos los
test*.py
módulos dentro deltest
paquete.fuente
python -m unittest discover
buscará y ejecutará pruebas en eltest
directorio si se nombrantest*.py
. Si nombró el subdirectoriotests
, usepython -m unittest discover -s tests
, y si nombró los archivos de pruebaantigravity_test.py
, usepython -m unittest discover -s tests -p '*test.py'
Los nombres de archivo pueden usar guiones bajos pero no guiones.ImportError: No module named 'test.test_antigravity'
debido a un conflicto con el submódulo de prueba de la biblioteca unittest. Tal vez un experto pueda confirmar y cambiar el nombre del subdirectorio de respuesta a, por ejemplo, 'pruebas' (plural).test_antigravity.py
todavía arroja un error de importación para ambosimport antigravity
yfrom antigravity import antigravity
, también. Tengo ambos__init_.py
archivos y estoy llamandopython3 -m unittest discover
desde elnew project
directorio. ¿Qué más podría estar mal?test/__init__.py
es crucial aquí, incluso si está vacíotest
es especial ... pero solo para el registro, no lo es. : Ppython -m unittest discover
funciona con archivos de pruebatests/
tan bien comotest/
.La solución más simple para sus usuarios es proporcionar un script ejecutable (
runtests.py
o algo similar) que inicie el entorno de prueba necesario, incluyendo, si es necesario, agregarsys.path
temporalmente el directorio del proyecto raíz . Esto no requiere que los usuarios establezcan variables de entorno, algo como esto funciona bien en un script de arranque:Entonces sus instrucciones para sus usuarios pueden ser tan simples como "
python runtests.py
".Por supuesto, si el camino que necesita realmente es
os.path.dirname(__file__)
, entonces no necesita agregarlosys.path
en absoluto; Python siempre coloca el directorio de la secuencia de comandos que se está ejecutando al principiosys.path
, por lo que, dependiendo de la estructura de su directorio, loruntests.py
único que necesita es ubicarlo en el lugar correcto.Además, el módulo unittest en Python 2.7+ (que está respaldado como unittest2 para Python 2.6 y versiones anteriores) ahora tiene el descubrimiento de prueba incorporado, por lo que ya no es necesario la nariz si desea un descubrimiento de prueba automatizado: sus instrucciones de usuario pueden ser tan simples como
python -m unittest discover
.fuente
python -m pdb tests\test_antigravity.py
. Dentro de pdb, ejecuté losys.path.insert(0, "antigravity")
que permitió que la declaración de importación se resolviera como si estuviera ejecutando el módulo.En general, creo un script de "ejecución de pruebas" en el directorio del proyecto (el que es común tanto para el directorio de origen como
test
) que carga mi suite "Todas las pruebas". Este suele ser un código repetitivo, por lo que puedo reutilizarlo de un proyecto a otro.run_tests.py:
test / all_tests.py (de ¿Cómo ejecuto todas las pruebas unitarias de Python en un directorio? )
Con esta configuración, puede de hecho solo
include antigravity
en sus módulos de prueba. La desventaja es que necesitaría más código de soporte para ejecutar una prueba en particular ... Simplemente los ejecuto todo el tiempo.fuente
run tests
script en el directorio del proyecto y encontré una forma mucho más limpia de hacerlo. Muy recomendable.Del artículo que vinculó a:
¿Quizás deberías mirar la nariz como sugiere?
fuente
Tuve el mismo problema, con una carpeta de pruebas unitarias separada. De las sugerencias mencionadas agrego la ruta de origen absoluta a
sys.path
.El beneficio de la siguiente solución es que uno puede ejecutar el archivo
test/test_yourmodule.py
sin cambiar al principio al directorio de prueba:fuente
si ejecuta "python setup.py development", el paquete estará en la ruta. Pero es posible que no desee hacerlo porque podría infectar la instalación de Python de su sistema, razón por la cual existen herramientas como virtualenv y buildout .
fuente
Solución / Ejemplo para el módulo de prueba unitaria de Python
Dada la siguiente estructura del proyecto:
Puede ejecutar su proyecto desde el directorio raíz con
python project_name
, que llamaProjectName/project_name/__main__.py
.Para ejecutar sus pruebas con
python test
una ejecución efectivaProjectName/test/__main__.py
, debe hacer lo siguiente:1) Convierta su
test/models
directorio en un paquete agregando un__init__.py
archivo. Esto hace que los casos de prueba dentro del subdirectorio sean accesibles desde eltest
directorio principal .2) Modifique la ruta de su sistema
test/__main__.py
para incluir elproject_name
directorio.Ahora puede importar cosas con éxito
project_name
en sus pruebas.fuente
Utilícelo
setup.py develop
para que su directorio de trabajo sea parte del entorno Python instalado, luego ejecute las pruebas.fuente
invalid command 'develop'
y esta opción no se menciona si lo pidosetup.py --help-commands
. ¿Es necesario que haya algo ensetup.py
sí mismo para que esto funcione?import setuptools
de misetup.py
archivo. Pero supongo que eso demuestra que esto no funcionará todo el tiempo para los módulos de otras personas.pip install -e .
Esto también agrega el paquete al entorno de Python sin copiar la fuente, lo que le permite continuar editándolo donde se encuentra.pip install -e .
es exactamente lo mismo, yapython setup.py develop
que solo usa parchessetup.py
para usar las herramientas de configuración, incluso si en realidad no lo hace, por lo que funciona de cualquier manera.Si usa VS Code y sus pruebas se encuentran en el mismo nivel que su proyecto, la ejecución y depuración de su código no funciona de inmediato. Lo que puede hacer es cambiar su archivo launch.json:
La línea clave aquí es envFile
En la raíz de su proyecto, agregue el archivo .env
Dentro de su archivo .env, agregue la ruta a la raíz de su proyecto. Esto agregará temporalmente
ruta de acceso a su proyecto y podrá utilizar pruebas de unidad de depuración de VS Code
fuente
Noté que si ejecuta la interfaz de línea de comando unittest desde su directorio "src", las importaciones funcionan correctamente sin modificación.
Si desea poner eso en un archivo por lotes en el directorio de su proyecto, puede hacer esto:
fuente
He tenido el mismo problema durante mucho tiempo. Lo que elegí recientemente es la siguiente estructura de directorios:
y en el
__init__.py
script de la carpeta de prueba, escribo lo siguiente:Súper importante para compartir el proyecto es el Makefile, porque obliga a ejecutar los scripts correctamente. Aquí está el comando que puse en el Makefile:
El Makefile es importante no solo por el comando que ejecuta sino también por el lugar desde donde lo ejecuta . Si hiciera un cd en las pruebas y lo hiciera
python -m unittest discover .
, no funcionaría porque el script de inicio en unit_tests llama a os.getcwd (), que luego apuntaría a la ruta absoluta incorrecta (que se agregaría a sys.path y faltaría) tu carpeta de origen). Los scripts se ejecutarían desde que find encuentra todas las pruebas, pero no se ejecutarán correctamente. Así que el Makefile está ahí para evitar tener que recordar este problema.Realmente me gusta este enfoque porque no tengo que tocar mi carpeta src, mis pruebas unitarias o mis variables de entorno y todo funciona sin problemas.
Avísame si les gusta.
Espero que ayude,
fuente
La siguiente es la estructura de mi proyecto:
Me pareció mejor importar en el método setUp ():
fuente
Yo uso Python 3.6.2
Para instalar pytest :
sudo pip install pytest
No configuré ninguna variable de ruta y mis importaciones no fallan con la misma estructura de proyecto de "prueba".
Comenté estas cosas:
if __name__ == '__main__'
así:test_antigravity.py
fuente
Es posible usar el contenedor que ejecuta las pruebas seleccionadas o todas.
Por ejemplo:
o para ejecutar todas las pruebas de forma recursiva use globbing (
tests/**/*.py
) (activar porshopt -s globstar
).El contenedor básicamente puede usarse
argparse
para analizar los argumentos como:Luego cargue todas las pruebas:
luego agréguelos a su conjunto de pruebas (usando
inspect
):y ejecutarlos:
Mira este ejemplo para más detalles.
Consulte también: ¿Cómo ejecutar todas las pruebas unitarias de Python en un directorio?
fuente
Python 3+
Agregando a @Pierre
Usando la
unittest
estructura de directorios de esta manera:Para ejecutar el módulo de prueba
test_antigravity.py
:O un solo
TestCase
Obligatorio , no olvide que
__init__.py
incluso si está vacío, de lo contrario no funcionará.fuente
No puede importar desde el directorio principal sin un poco de vudú. Aquí hay otra forma que funciona con al menos Python 3.6.
Primero, tenga un archivo test / context.py con el siguiente contenido:
Luego tenga la siguiente importación en el archivo test / test_antigravity.py:
Tenga en cuenta que la razón de esta cláusula try-except es que
Con este truco, ambos trabajan.
Ahora puede ejecutar todos los archivos de prueba dentro del directorio de prueba con:
o ejecutar un archivo de prueba individual con:
Ok, no es mucho más bonito que tener el contenido de context.py dentro de test_antigravity.py, pero quizás un poco. Las sugerencias son bienvenidas.
fuente
Si tiene varios directorios en su directorio de prueba, entonces debe agregar a cada directorio un
__init__.py
archivo.Luego, para ejecutar cada prueba a la vez, ejecute:
Fuente:
python -m unittest -h
fuente
Este script de BASH ejecutará el directorio de prueba de prueba de unidad de Python desde cualquier parte del sistema de archivos, sin importar en qué directorio de trabajo se encuentre.
Esto es útil cuando se está en el directorio
./src
o en el./example
trabajo y necesita una prueba de unidad rápida:No es necesario que un
test/__init__.py
archivo cargue su paquete / sobrecarga de memoria durante la producción.fuente
De esta manera, podrá ejecutar los scripts de prueba desde donde desee sin perder el tiempo con las variables del sistema desde la línea de comandos.
Esto agrega la carpeta principal del proyecto a la ruta de Python, con la ubicación encontrada en relación con el script en sí, no en relación con el directorio de trabajo actual.
Agregue eso a la parte superior de todos sus scripts de prueba. Eso agregará la carpeta principal del proyecto a la ruta del sistema, por lo que cualquier importación de módulos que funcione desde allí ahora funcionará. Y no importa desde dónde ejecute las pruebas.
Obviamente, puede cambiar el archivo project_path_hack para que coincida con la ubicación de su carpeta principal del proyecto.
fuente
Si está buscando una solución de línea de comandos solamente:
Basado en la siguiente estructura de directorios (generalizada con un directorio fuente dedicado):
Windows : (en
new_project
)Vea esta pregunta si desea usar esto en un lote for-loop.
Linux : (en
new_project
)Con este enfoque, también es posible agregar más directorios a PYTHONPATH si es necesario.
fuente
Realmente deberías usar la herramienta pip.
Úselo
pip install -e .
para instalar su paquete en modo de desarrollo. Esta es una muy buena práctica, recomendada por pytest (consulte su documentación de buenas prácticas , donde también puede encontrar dos diseños de proyectos para seguir).fuente
pytest
es mucho mejor ejecutar pruebas, debido a la salida de la consola que obtienes, en color, con información de seguimiento de la pila e información detallada de error de aserción.