¿Cuál es la diferencia entre setUp () y setUpClass () en Python unittest?

99

¿Cuál es la diferencia entre setUp()y setUpClass()en el unittestmarco de Python ? ¿Por qué la configuración se manejaría en un método sobre el otro?

Quiero comprender qué parte de la configuración se realiza en las funciones setUp()y setUpClass(), así como con tearDown()y tearDownClass().

etja
fuente

Respuestas:

147

La diferencia se manifiesta cuando tiene más de un método de prueba en su clase. setUpClassy tearDownClassse ejecutan una vez para toda la clase; setUpy tearDownse ejecutan antes y después de cada método de prueba.

Por ejemplo:

class Example(unittest.TestCase):
    @classmethod
    def setUpClass(cls):
        print("setUpClass")

    def setUp(self):
        print("setUp")

    def test1(self):
        print("test1")

    def test2(self):
        print("test2")

    def tearDown(self):
        print("tearDown")

    @classmethod
    def tearDownClass(cls):
        print("tearDownClass")

Cuando ejecuta esta prueba, imprime:

setUpClass
setUp
test1
tearDown
.setUp
test2
tearDown
.tearDownClass

(Los puntos ( .) son unittestla salida predeterminada cuando pasa una prueba). Observe que setUpy tearDownaparecen antes y después test1 y test2 , mientras que setUpClassy tearDownClassaparecen sólo una vez, al principio y al final de todo el caso de prueba.

Benjamin Hodgson
fuente
¿No debería ser este el orden? : setUpClass setUp test1 tearDown .setUp test2 .tearDown tearDownClass
Jai Sharma
Observe la "." delante de tearDown y la ausencia de "." frente a tearDownClass
Jai Sharma
Ah, lo siento, no me di cuenta de eso. No, unittestno considera que una prueba haya pasado hasta que se tearDownhaya completado sin incidentes.
Benjamin Hodgson
Entonces, cada uno de los métodos test1 y test2 debería tener su propio conjunto de setUp & tearDown, ¿verdad? En su respuesta, test1 no tiene ningún método tearDown y, por lo tanto, debería haber impreso la salida predeterminada (con.). Corrígeme si me equivoco.
Jai Sharma
1
El resultado de la respuesta es correcto. Lo pegué directamente de la salida de unittest. setUpy tearDownse ejecutan una vez para cada testmétodo (es decir, dos veces en total en este ejemplo) pero setUpClassy tearDownClassse ejecutan solo una vez cada uno.
Benjamin Hodgson
15

¿Cuál es la diferencia entre setUp()y setUpClass()en el unittestmarco de Python ?

La principal diferencia (como se señaló en la respuesta de Benjamin Hodgson) es que setUpClassse llama solo una vez y es antes de todas las pruebas, mientras que setUpse llama inmediatamente antes de todas y cada una de las pruebas. (NB: Lo mismo se aplica a los métodos equivalentes en otros marcos de prueba de xUnit, no solo a los de Python unittest).

De la unittest documentación :

setUpClass()

Un método de clase llamado antes de que se ejecuten las pruebas en una clase individual. setUpClass se llama con la clase como único argumento y debe decorarse como un método de clase ():

@classmethod
def setUpClass(cls):
    ...

y:

setUp()

Método llamado para preparar el dispositivo de prueba. Esto se llama inmediatamente antes de llamar al método de prueba; que no sea AssertionError o SkipTest, cualquier excepción generada por este método se considerará un error en lugar de un error de prueba. La implementación predeterminada no hace nada.

¿Por qué la configuración se manejaría en un método sobre el otro?

Esta parte de la pregunta aún no ha sido respondida. Según mi comentario en respuesta a la respuesta de Gearon, el setUpmétodo está destinado a elementos del accesorio que son comunes a todas las pruebas (para evitar duplicar ese código en cada prueba). Encuentro que esto a menudo es útil ya que eliminar la duplicación (generalmente) mejora la legibilidad y reduce la carga de mantenimiento.

El setUpClassmétodo es para elementos costosos que preferiría tener que hacer una sola vez, como abrir una conexión de base de datos, abrir un archivo temporal en el sistema de archivos, cargar una biblioteca compartida para probar, etc. Hacer tales cosas antes de cada prueba ralentizaría el conjunto de pruebas demasiado, por lo que solo lo hacemos una vez antes de todas las pruebas. Esta es una ligera degradación en la independencia de las pruebas pero una optimización necesaria en algunas situaciones. Podría decirse que uno no debería hacer tales cosas en pruebas unitarias, ya que generalmente es posible burlarse de la base de datos / sistema de archivos / biblioteca / lo que sea sin usar la cosa real. Como tal, encuentro que setUpClassrara vez se necesita. Sin embargo, es útil cuando es necesario probar los ejemplos anteriores (o similares).

Biggsy
fuente