¿Cómo se prueba que una función de Python genera una excepción?

Resuelto Daryl Spitzer asked hace 16 años • 19 respuestas

¿Cómo se escribe una prueba unitaria que falla solo si una función no genera una excepción esperada?

Daryl Spitzer avatar Sep 25 '08 03:09 Daryl Spitzer
Aceptado

Utilice TestCase.assertRaisesdesde el unittestmódulo, por ejemplo:

import mymod

class MyTestCase(unittest.TestCase):
    def test1(self):
        self.assertRaises(SomeCoolException, mymod.myfunc)
Moe avatar Sep 24 '2008 20:09 Moe

Desde Python 2.7, puede usar el administrador de contexto para obtener el objeto de excepción real lanzado:

import unittest

def broken_function():
    raise Exception('This is broken')

class MyTestCase(unittest.TestCase):
    def test(self):
        with self.assertRaises(Exception) as context:
            broken_function()

        self.assertTrue('This is broken' in context.exception)

if __name__ == '__main__':
    unittest.main()

afirmarAumentos


En Python 3.5 , tienes que ajustarlo context.exception, strde lo contrario obtendrás unTypeError

self.assertTrue('This is broken' in str(context.exception))
Art avatar Jul 02 '2010 15:07 Art

El código de mi respuesta anterior se puede simplificar a:

def test_afunction_throws_exception(self):
    self.assertRaises(ExpectedException, afunction)

Y si una función toma argumentos, simplemente páselos a afirmarRaises así:

def test_afunction_throws_exception(self):
    self.assertRaises(ExpectedException, afunction, arg1, arg2)
Daryl Spitzer avatar Sep 24 '2008 20:09 Daryl Spitzer

¿Cómo se prueba que una función de Python genera una excepción?

¿Cómo se escribe una prueba que falla sólo si una función no genera una excepción esperada?

Respuesta corta:

Utilice el self.assertRaisesmétodo como administrador de contexto:

    def test_1_cannot_add_int_and_str(self):
        with self.assertRaises(TypeError):
            1 + '1'

Demostración

El enfoque de mejores prácticas es bastante fácil de demostrar en un shell de Python.

La unittestbiblioteca

En Python 2.7 o 3:

import unittest

En Python 2.6, puede instalar un backport de la unittestbiblioteca 2.7, llamado unittest2 , y simplemente alias eso como unittest:

import unittest2 as unittest

Pruebas de ejemplo

Ahora, pega en tu shell de Python la siguiente prueba de seguridad de tipos de Python:

class MyTestCase(unittest.TestCase):
    def test_1_cannot_add_int_and_str(self):
        with self.assertRaises(TypeError):
            1 + '1'
    def test_2_cannot_add_int_and_str(self):
        import operator
        self.assertRaises(TypeError, operator.add, 1, '1')

La prueba que uno utiliza assertRaisescomo administrador de contexto, lo que garantiza que el error se detecte y limpie adecuadamente, mientras se registra.

También podríamos escribirlo sin el administrador de contexto, consulte la prueba dos. El primer argumento sería el tipo de error que espera generar, el segundo argumento, la función que está probando y los argumentos restantes y los argumentos de palabras clave se pasarán a esa función.

Creo que es mucho más simple, legible y fácil de mantener simplemente usar el administrador de contexto.

ejecutando las pruebas

Para ejecutar las pruebas:

unittest.main(exit=False)

En Python 2.6, probablemente necesitarás lo siguiente :

unittest.TextTestRunner().run(unittest.TestLoader().loadTestsFromTestCase(MyTestCase))

Y su terminal debería generar lo siguiente:

..
----------------------------------------------------------------------
Ran 2 tests in 0.007s

OK
<unittest2.runner.TextTestResult run=2 errors=0 failures=0>

Y vemos eso como esperábamos, al intentar agregar un 1y un '1'resultado en un TypeError.


Para obtener resultados más detallados, intente esto:

unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromTestCase(MyTestCase))
Russia Must Remove Putin avatar Jan 29 '2015 19:01 Russia Must Remove Putin