sintaxis resueltos recursivo recursividad recursivas numero mayor funciones ejercicios algoritmo python python-2.7 python-unittest

python - resueltos - Prueba de unidad recursiva descubrir



recursividad en c++ pdf (2)

Al hacer un poco de excavación, parece que mientras los módulos más profundos sigan siendo importantes, se descubrirán a través de python -m unittest discover . La solución, entonces, era simplemente agregar un archivo __init__.py a cada directorio para hacerlos paquetes.

. ├── LICENSE ├── models │   └── __init__.py ├── README.md ├── requirements.txt ├── tc.py ├── tests │   ├── db │   │   ├── __init__.py # NEW │   │   └── test_employee.py │   ├── __init__.py # NEW │   └── test_tc.py └── todo.txt

Mientras cada directorio tenga un __init__.py , python -m unittest discover puede importar el módulo test_* relevante.

Tengo un paquete con un directorio "pruebas" en el que estoy almacenando mis pruebas unitarias. Mi paquete se ve como:

. ├── LICENSE ├── models │   └── __init__.py ├── README.md ├── requirements.txt ├── tc.py ├── tests │   ├── db │   │   └── test_employee.py │   └── test_tc.py └── todo.txt

Desde el directorio de mi paquete, quiero poder encontrar las tests/test_tc.py y las tests/db/test_employee.py . Prefiero no tener que instalar una biblioteca de terceros ( nose o etc.) o tengo que crear manualmente un TestSuite para ejecutar esto.

¿Seguramente hay una manera de decirle a unittest discover no debe dejar de buscar una vez que se encuentra una prueba? python -m unittest discover -s tests encontrarán las tests/test_tc.py y python -m unittest discover -s tests/db encontrarán las tests/db/test_employee.py . ¿No hay una manera de encontrar ambos?


Si está de acuerdo con agregar un archivo __init__.py dentro de las pruebas, puede poner allí una función load_tests que manejará el descubrimiento por usted.

Si el nombre de un paquete de prueba (directorio con __init__.py ) coincide con el patrón, el paquete verificará la función ''load_tests''. Si esto existe, se llamará con cargador, pruebas, patrón.

Si existe load_tests, entonces el descubrimiento no retrocede en el paquete, load_tests es responsable de cargar todas las pruebas en el paquete.

Estoy lejos de estar seguro de que esta es la mejor manera, pero una forma de escribir esa función sería:

import os import pkgutil import inspect import unittest # Add *all* subdirectories to this module''s path __path__ = [x[0] for x in os.walk(os.path.dirname(__file__))] def load_tests(loader, suite, pattern): for imp, modname, _ in pkgutil.walk_packages(__path__): mod = imp.find_module(modname).load_module(modname) for memname, memobj in inspect.getmembers(mod): if inspect.isclass(memobj): if issubclass(memobj, unittest.TestCase): print("Found TestCase: {}".format(memobj)) for test in loader.loadTestsFromTestCase(memobj): print(" Found Test: {}".format(test)) suite.addTest(test) print("=" * 70) return suite

Bastante feo, estoy de acuerdo.

Primero, agregue todos los subdirectorios a la ruta de los paquetes de prueba ( Docs ).

Luego, usa pkgutil para recorrer el camino, buscando paquetes o módulos.

Cuando encuentra uno, luego verifica los miembros del módulo para ver si son clases, y si son clases, si son subclases de unittest.TestCase . Si lo son, las pruebas dentro de las clases se cargan en el conjunto de pruebas.

Así que ahora, desde dentro de la raíz de su proyecto, puede escribir

python -m unittest discover -p tests

Usando el interruptor de patrón -p . Si todo va bien, verás lo que vi, que es algo así como:

Found TestCase: <class ''test_tc.TestCase''> Found Test: testBar (test_tc.TestCase) Found Test: testFoo (test_tc.TestCase) Found TestCase: <class ''test_employee.TestCase''> Found Test: testBar (test_employee.TestCase) Found Test: testFoo (test_employee.TestCase) ====================================================================== .... ---------------------------------------------------------------------- Ran 4 tests in 0.001s OK

Que es lo que se esperaba, cada uno de mis dos archivos de ejemplo contenía dos pruebas, testFoo y testBar cada una.

Edición: después de algunas excavaciones más, parece que podría especificar esta función como:

def load_tests(loader, suite, pattern): for imp, modname, _ in pkgutil.walk_packages(__path__): mod = imp.find_module(modname).load_module(modname) for test in loader.loadTestsFromModule(mod): print("Found Tests: {}".format(test._tests)) suite.addTests(test)

Esto utiliza el método loader.loadTestsFromModule() lugar del método loader.loadTestsFromTestCase() que usé anteriormente. Todavía modifica la ruta del paquete de tests y lo recorre en busca de módulos, lo que creo que es la clave aquí.

La salida se ve un poco diferente ahora, ya que estamos agregando un testuite encontrado a la vez a nuestra suite principal de testsuite:

python -m unittest discover -p tests Found Tests: [<test_tc.TestCase testMethod=testBar>, <test_tc.TestCase testMethod=testFoo>] Found Tests: [<test_employee.TestCase testMethod=testBar>, <test_employee.TestCase testMethod=testFoo>] ====================================================================== .... ---------------------------------------------------------------------- Ran 4 tests in 0.000s OK

Pero aún obtenemos las 4 pruebas que esperábamos, en ambas clases, en ambos subdirectorios.