¿Cómo se prueba que una función de Python genera una excepción?
¿Cómo se escribe una prueba unitaria que falla solo si una función no genera una excepción esperada?
Utilice TestCase.assertRaises
desde el unittest
módulo, por ejemplo:
import mymod
class MyTestCase(unittest.TestCase):
def test1(self):
self.assertRaises(SomeCoolException, mymod.myfunc)
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
, str
de lo contrario obtendrás unTypeError
self.assertTrue('This is broken' in str(context.exception))
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)
¿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.assertRaises
mé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 unittest
biblioteca
En Python 2.7 o 3:
import unittest
En Python 2.6, puede instalar un backport de la unittest
biblioteca 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 assertRaises
como 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 1
y un '1'
resultado en un TypeError
.
Para obtener resultados más detallados, intente esto:
unittest.TextTestRunner(verbosity=2).run(unittest.TestLoader().loadTestsFromTestCase(MyTestCase))