Tengo un directorio que contiene mis pruebas unitarias de Python. Cada módulo de prueba unitaria tiene la forma test _ *. Py . Estoy intentando crear un archivo llamado all_test.py que, lo adivinaste , ejecutará todos los archivos en el formulario de prueba mencionado anteriormente y devolverá el resultado. He probado dos métodos hasta ahora; Ambos han fallado. Mostraré los dos métodos, y espero que alguien sepa cómo hacerlo correctamente.
Para mi primer intento valiente, pensé "Si solo importo todos mis módulos de prueba en el archivo y luego llamo a este unittest.main()
doodad, funcionará, ¿verdad?" Bueno, resulta que estaba equivocado.
import glob
import unittest
testSuite = unittest.TestSuite()
test_file_strings = glob.glob('test_*.py')
module_strings = [str[0:len(str)-3] for str in test_file_strings]
if __name__ == "__main__":
unittest.main()
Esto no funcionó, el resultado que obtuve fue:
$ python all_test.py
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
Sin embargo, para mi segundo intento, bueno, tal vez intentaré hacer todo este proceso de prueba de una manera más "manual". Así que intenté hacer eso a continuación:
import glob
import unittest
testSuite = unittest.TestSuite()
test_file_strings = glob.glob('test_*.py')
module_strings = [str[0:len(str)-3] for str in test_file_strings]
[__import__(str) for str in module_strings]
suites = [unittest.TestLoader().loadTestsFromName(str) for str in module_strings]
[testSuite.addTest(suite) for suite in suites]
print testSuite
result = unittest.TestResult()
testSuite.run(result)
print result
#Ok, at this point I have a result
#How do I display it as the normal unit test command line output?
if __name__ == "__main__":
unittest.main()
Esto tampoco funcionó, ¡pero parece tan cerca!
$ python all_test.py
<unittest.TestSuite tests=[<unittest.TestSuite tests=[<unittest.TestSuite tests=[<test_main.TestMain testMethod=test_respondes_to_get>]>]>]>
<unittest.TestResult run=1 errors=0 failures=0>
----------------------------------------------------------------------
Ran 0 tests in 0.000s
OK
Parece que tengo una suite de algún tipo, y puedo ejecutar el resultado. Estoy un poco preocupado por el hecho de que dice que solo tengo run=1
, parece que debería ser run=2
, pero es un progreso. Pero, ¿cómo paso y visualizo el resultado a main? ¿O cómo básicamente lo hago funcionar para poder ejecutar este archivo y, al hacerlo, ejecutar todas las pruebas unitarias en este directorio?
fuente
Respuestas:
Con Python 2.7 y versiones posteriores, no tiene que escribir código nuevo ni usar herramientas de terceros para hacer esto; La ejecución de prueba recursiva a través de la línea de comando está incorporada. Ponga un
__init__.py
en su directorio de prueba y:Puede leer más en la documentación de Python 2.7 o Python 3.x unittest.
fuente
Podrías usar un corredor de prueba que haría esto por ti. La nariz es muy buena, por ejemplo. Cuando se ejecuta, encontrará pruebas en el árbol actual y las ejecutará.
Actualizado:
Aquí hay un código de mis días previos a la nariz. Probablemente no desee la lista explícita de nombres de módulos, pero quizás el resto le sea útil.
fuente
En Python 3, si estás usando
unittest.TestCase
:__init__.py
archivo vacío (o no) en sutest
directorio ( debe tener un nombretest/
)test/
coinciden con el patróntest_*.py
. Pueden estar dentro de un subdirectorio debajotest/
, y esos subdirectorios pueden nombrarse como cualquier cosa.Luego, puede ejecutar todas las pruebas con:
¡Hecho! Una solución de menos de 100 líneas. Esperemos que otro principiante de Python ahorre tiempo al encontrar esto.
fuente
Esto ahora es posible directamente desde unittest: unittest.TestLoader.discover .
fuente
.... ---------------------------------------------------------------------- Ran 4 tests in 0.000s OK
¿Por qué? La diferencia, ¿de dónde viene?python file.py
Bueno, al estudiar un poco el código anterior (específicamente usando
TextTestRunner
ydefaultTestLoader
), pude acercarme bastante. Finalmente, arreglé mi código simplemente pasando todas las suites de prueba a un solo constructor de suites, en lugar de agregarlas "manualmente", lo que solucionó mis otros problemas. Entonces aquí está mi solución.Sí, probablemente sea más fácil usar la nariz que hacer esto, pero eso no viene al caso.
fuente
Si desea ejecutar todas las pruebas de varias clases de casos de prueba y está feliz de especificarlas explícitamente, puede hacerlo así:
donde
uclid
está mi proyectoTestSymbols
yTestPatterns
son subclases deTestCase
.fuente
TestSuite
acepta un iterable como argumento, puede construir dicho iterable en un bucle para evitar repetirloloader.loadTestsFromTestCase
.He utilizado el
discover
método y una sobrecarga deload_tests
para lograr este resultado en un número (mínimo, creo) de líneas de código:Ejecución en cinco años algo así como
fuente
Intenté varios enfoques, pero todos parecen defectuosos o tengo que inventar un código, eso es molesto. Pero hay una manera conveniente en Linux, que es simplemente encontrar cada prueba a través de cierto patrón y luego invocarlas una por una.
y lo más importante, definitivamente funciona.
fuente
En el caso de una biblioteca o aplicación empaquetada , no desea hacerlo.
setuptools
Lo hará por ti .Solo dígale dónde está su paquete de prueba raíz, como:
Y ejecutar
python setup.py test
.El descubrimiento basado en archivos puede ser problemático en Python 3, a menos que evite las importaciones relativas en su conjunto de pruebas, ya que
discover
utiliza la importación de archivos. A pesar de que admite opcionaltop_level_dir
, pero tuve algunos errores de recursión infinita. Entonces, una solución simple para un código no empaquetado es poner lo siguiente en__init__.py
su paquete de prueba (vea el protocolo load_tests ).fuente
Utilizo PyDev / LiClipse y realmente no he descubierto cómo ejecutar todas las pruebas a la vez desde la GUI. (editar: hace clic derecho en la carpeta de prueba raíz y elige
Run as -> Python unit-test
Esta es mi solución actual:
Puse este código en un módulo llamado
all
en mi directorio de prueba. Si ejecuto este módulo como una prueba unitaria de LiClipse, se ejecutarán todas las pruebas. Si solo pido repetir pruebas específicas o fallidas, solo se ejecutan esas pruebas. Tampoco interfiere con mi corredor de prueba de línea de comandos (pruebas nasales): se ignora.Es posible que deba cambiar los argumentos
discover
según la configuración de su proyecto.fuente
Basado en la respuesta de Stephen Cagle , agregué soporte para módulos de prueba anidados.
El código busca en todos los subdirectorios
.
de*Tests.py
archivos que se cargan a continuación. Se espera que cada uno*Tests.py
contenga una sola clase*Tests(unittest.TestCase)
que se carga a su vez y se ejecuta una tras otra.Esto funciona con anidamiento profundo arbitrario de directorios / módulos, pero cada directorio intermedio debe contener
__init__.py
al menos un archivo vacío . Esto permite que la prueba cargue los módulos anidados mediante la sustitución de barras (o barras invertidas) por puntos (verreplace_slash_by_dot
).fuente
Esta es una vieja pregunta, pero lo que funcionó para mí ahora (en 2019) es:
Todos mis archivos de prueba están en la misma carpeta que los archivos de origen y terminan en
_test
.fuente
Debido a que el descubrimiento de prueba parece ser un tema completo, existe un marco dedicado para probar el descubrimiento:
Más información aquí: https://wiki.python.org/moin/PythonTestingToolsTaxonomy
fuente
Este script de BASH ejecutará el directorio de prueba de prueba de unidad de Python desde CUALQUIER LUGAR del sistema de archivos, sin importar en qué directorio de trabajo se encuentre: su directorio de trabajo siempre estará donde
test
esté ubicado ese directorio.TODAS LAS PRUEBAS, $ PWD independiente
El módulo de Python unittest es sensible a su directorio actual, a menos que le indique dónde (usando la
discover -s
opción).Esto es útil cuando permanece en el directorio
./src
o en el./example
trabajo y necesita una prueba general rápida de la unidad:PRUEBAS SELECCIONADAS, independientes $ PWD
Nombre este archivo de utilidad:
runone.py
y lo uso así:No es necesario que un
test/__init__.py
archivo cargue su paquete / sobrecarga de memoria durante la producción.fuente
Aquí está mi enfoque creando un contenedor para ejecutar pruebas desde la línea de comandos:
En aras de la simplicidad, disculpe mis estándares de codificación que no son PEP8 .
Luego puede crear la clase BaseTest para componentes comunes para todas sus pruebas, de modo que cada una de sus pruebas simplemente se vea así:
Para ejecutar, simplemente especifica las pruebas como parte de los argumentos de la línea de comandos, por ejemplo:
fuente