Recargar unittest en Python

Israel Fernández Cabrera iferca en gmail.com
Mie Jul 4 17:38:14 CEST 2007


Hola:

Creo que el asunto no refleja exactamente mi duda pero bueno, el
problema que tengo es el siguiente.
Estoy escribiendo un código que ejecuta unittests, en la misma corrida
del programa las pruebas de unidad (unittest) pueden cambiar y se
ejecutan de nuevo, como en este código de ejemplo que reproduce el
problema:

<código require="salvar en fichero de nombre import_tests.py">
class PruebasDePrueba(unittest.TestCase):
    def testUnTest(self):
        a = 2
        b = 1
        self.assertEquals(a, b)

def runTests():
    loader = unittest.TestLoader()
    result = unittest.TestResult()
    suite = loader.loadTestsFromName("import_tests.PruebasDePrueba")
    suite.run(result)
    print "Errores: ", len(result.errors)
    print "Fallos: ", len(result.failures)

if __name__ == "__main__":
    runTests()
    raw_input("Modifique el test y presione ENTER para continuar")
</código>

El código ejecuta los tests de la clase PruebasDePrueba, le pide que
lo modifique y luego los ejecuta de nuevo después de presionar ENTER.
El estado inicial de la prueba es "fallo" así que haciendo a y b
iguales en la segunda corrida se esperaría que la prueba no falle,
pero sigue fallando.
Ya he modificado el código real de mil maneras, los tests se ejecutan
en un hilo separado, todas las variables, al igual que en el ejemplo,
se inicializan con cada corrida.
Como dato curioso, el ejemplo carga los test de
"import_tests.PruebasDePrueba", que es un TestCase, si la cadena
hiciera referencia a un módulo, resolví el problema heredando de
unittest.TestLoader y redefiniendo el método
loadTestsFromModule(module) y haciendo un module = reload(module) y
luego dejando que se ejecute el método del padre. Pero en el caso de
los TestCase no lo logro y no se porqué.
Para facilitar la ayuda copio aquí el código del método
loadTestsFromName de unittest.TestLoader:

<código>
def loadTestsFromName(self, name, module=None):
        """Return a suite of all tests cases given a string specifier.

        The name may resolve either to a module, a test case class, a
        test method within a test case class, or a callable object which
        returns a TestCase or TestSuite instance.

        The method optionally resolves the names relative to a given module.
        """
        parts = name.split('.')
        if module is None:
            parts_copy = parts[:]
            while parts_copy:
                try:
                    module = __import__('.'.join(parts_copy))
                    break
                except ImportError:
                    del parts_copy[-1]
                    if not parts_copy: raise
            parts = parts[1:]
        obj = module
        for part in parts:
            parent, obj = obj, getattr(obj, part)

        if type(obj) == types.ModuleType:
            return self.loadTestsFromModule(obj)
        elif (isinstance(obj, (type, types.ClassType)) and
              issubclass(obj, TestCase)):
            return self.loadTestsFromTestCase(obj)
        elif type(obj) == types.UnboundMethodType:
            return parent(obj.__name__)
        elif isinstance(obj, TestSuite):
            return obj
        elif callable(obj):
            test = obj()
            if not isinstance(test, (TestCase, TestSuite)):
                raise ValueError, \
                      "calling %s returned %s, not a test" % (obj,test)
            return test
        else:
            raise ValueError, "don't know how to make test from: %s" % obj
</código>

gracias de antemano,
S en lu2

-- 
____________________
Israel Fdez. Cabrera
iferca en gmail.com

 . 0 .
 . . 0
 0 0 0




Más información sobre la lista de distribución Python-es