Saltar al contenido

Python unittest TestCase con herencia

Solución:

Un poco tarde aquí, pero recientemente surgió la necesidad de tener herencia de prueba unitaria

La solución más elegante que pude encontrar es esta:

Primero, necesitas una clase de prueba base

class MyBaseUnitTest(unittest.TestCase):
    __test__ = False
    def test_someting(self):
        ...

    def test_something_else(self):
        ...

luego para heredar esa clase y ejecutar pruebas:

class TestA(MyBaseUnitTest):
    __test__ = True

    def test_feature(self):
        pass
    def test_feature2(self):
        pass

Ésta es la mejor y más sencilla forma de tener una herencia de conjunto de vistas único.

El problema que encontré con la herencia múltiple es que cuando intentas invocar métodos como setUp() no se llamará en la clase de prueba base, por lo que debe llamarlo en cada clase que escriba que amplíe la clase base.

Espero que esto ayude a alguien con esto en el futuro.

Por cierto: esto se hizo en python3, no sé cómo reaccionará en python2

ACTUALIZAR:

Esto es probablemente mejor y más pitónico.

class MyBaseUnitTest(object):
    def test_someting(self):
        ...

    def test_something_else(self):
        ...

class TestA(MyBaseUnitTest, unittest.TestCase):

    def test_feature(self):
        pass
    def test_feature2(self):
        pass

Siempre que la clase de prueba base no extienda “unittest.TestCase”, el ejecutor de la prueba no resolverá estas pruebas y no se ejecutarán en la suite. Solo se ejecutarán donde la clase base los extienda.

Para que esto funcione como se espera, como mínimo necesita:

  • Asegúrate que en eso El método de los casos de prueba de sus subclases coincide con el de TestCase, es decir __init__(self, methodName="runTest")
  • Agrega una súper llamada en el en eso método de sus subclases, por ejemplo super(TestMyClass, self).__init__(methodName)
  • Agregue un argumento propio a test_get_result, es decir def test_get_result(self):

En cuanto a si es un buen diseño, recuerde, sus pruebas actúan en parte como documentación de cómo debe funcionar su código. Si tiene todo el trabajo oculto en el estado de la instancia de TestCase, lo que hace no será tan obvio. Es posible que sea mejor, por ejemplo, escribir una clase mixin que tenga aserciones personalizadas que tomen entradas y salidas esperadas.

El diseño es (más o menos) bueno – el único “inconveniente” es que cuando unittest mira todos TestCase clasifica y ejecuta los métodos que comienzan con “prueba” en ellos. Tiene algunas opciones en este momento.

Un enfoque sería especificar la clase bajo prueba y los valores como atributos en el clase. Aquí, si es posible, querrá que los valores sean inmutables …

class TestBase(unittest.TestCase):

    def check(self, input, expected_output):
        obj = self.class_under_test(input)
        actual_output = obj.get_result()
        self.assertEqual(actual_output, expected_output)

    def check_all(self):
        for value in self.values:
            self.check(value[0], value[1])

class TestMyClass1(TestBase):
    values = ((1, 2), (3, 4))
    class_under_test = MyClass1

    def test_it(self):
        self.check_all()

class TestMyClass2(TestBase):
    values = (('a', 'b'), ('d', 'e'))
    class_under_test = MyClass2

    def test_it(self):
        self.check_all()
¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *