Python assert Excepción
- Uso de Context Manager para detectar la excepción de afirmación de Python
- Uso de argumentos de palabras clave para detectar la excepción de afirmación de Python
Este artículo lleva a uno a comprender el concepto assert
como una unidad de prueba, para probar que las funciones pueden generar excepciones (errores detectados durante la ejecución del código) sin necesariamente salir de la ejecución. En otras palabras, la excepción lanzada está encapsulada.
Esta prueba pasará si se genera una excepción. Se produce un error si se lanza una excepción diferente a la esperada. En una instancia en la que no se genera ninguna excepción, la prueba falla.
Uso de Context Manager para detectar la excepción de afirmación de Python
De manera similar a cómo permite la asignación y liberación de recursos cuando es necesario en el concepto general de Python, el contexto aquí se apodera del objeto de excepción real que se lanza durante la prueba.
Almacena este atributo de excepción en el objeto si es necesario realizar una verificación de rendimiento adicional en la excepción generada.
Para probar que una función falla o pasa si se lanza una excepción o no, emplearemos TestCase.assertRaises
del módulo unittest
.
Veamos un ejemplo práctico usando el administrador de contexto.
import unittest
class TestCase(unittest.TestCase):
def test_nameerror(self):
with self.assertRaises(Exception):
100 * (someNumber / 5)
if __name__ == "__main__":
unittest.main()
Producción :
.
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
En el código de ejemplo, la prueba pasa porque esperamos que se lance una excepción. Estamos dividiendo 5 por una variable indefinida someNumber
. Por lo tanto, la función lanza una excepción NameError
. Por lo tanto, nuestra prueba pasa como se muestra en .
en la primera línea de la salida.
Veamos un ejemplo en el que la prueba falla cuando no se lanza una excepción.
import unittest
class TestCase(unittest.TestCase):
def test_nameerror(self):
with self.assertRaises(Exception):
someNumber = 10
100 * (someNumber / 5)
if __name__ == "__main__":
unittest.main()
Producción :
F
======================================================================
FAIL: test_nameerror (__main__.MyTestCase)
----------------------------------------------------------------------
Traceback (most recent call last): File "c:\Users\Neema\Desktop\Article Requirement Spec and Example
Articles\Article Requirement Spec
and Example Articles\fah.py", line 106, in test_nameerror
100 * (someNumber/5)
AssertionError: Exception not raised
----------------------------------------------------------------------
Ran 1 test in 0.002s
FAILED (failures=1)
En este código de ejemplo, definimos un valor para someNumber
y luego realizamos la expresión aritmética con él.
El resultado nos muestra que la prueba falla como se esperaba. No esperamos que se lance ninguna excepción de NameError
esta vez, ya que existe un valor definido para someNumber
.
También podemos implementar el administrador de contexto usando excepciones definidas por el usuario como en el siguiente ejemplo.
import unittest
def user_function():
raise Exception("A user-defined exception")
class MyTestCase(unittest.TestCase):
def test_userexception(self):
with self.assertRaises(Exception) as context:
user_function()
self.assertTrue("A user-defined exception" in str(context.exception))
if __name__ == "__main__":
unittest.main()
Producción :
.
----------------------------------------------------------------------
Ran 1 test in 0.006s
OK
Recuerde usar
str
para encerrar lacontext.exception
para evitar obtener un TypeError.
Introducimos assertTrue
, una biblioteca de unittest
que compara un valor de prueba con verdadero en las pruebas unitarias.
También puede optar por utilizar assertIn
en lugar de assertTrue.
Ejemplo:
import unittest
def user_function():
raise Exception("A use defined exception")
class MyTestCase(unittest.TestCase):
def test_userexception(self):
with self.assertRaises(Exception) as context:
user_function()
self.assertIn("A use defined exception", str(context.exception))
if __name__ == "__main__":
unittest.main()
Vemos la misma salida donde se producirán los pases de prueba.
Uso de argumentos de palabras clave para detectar la excepción de afirmación de Python
A diferencia del administrador de contexto, donde solo pasamos la excepción a assertRaises()
, también pasamos la llamada a la función y los parámetros de la función como argumentos de palabras clave para evocar la excepción.
Sintaxis
assertRaises(exception, function, *args, **keywords)
Ejemplo:
import unittest
class MyTestCase(unittest.TestCase):
def test_division_by_error(self):
import operator
self.assertRaises(ZeroDivisionError, operator.floordiv, 55, 0)
if __name__ == "__main__":
unittest.main()
Producción :
.
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
El código de ejemplo anterior usó assertRaises()
con argumentos de palabras clave. Le pasamos la excepción ZeroDivisionError
esperada después de intentar dividir un número con cero. Importamos la función de operador usada con la función de operador floordiv
como segundo argumento. Los valores de los parámetros aquí son los terceros parámetros; 55 para dividir por 0.
La última aplicación de assert es cuando pasamos una excepción diferente a la esperada a assertRaises()
. En cambio, se produce un error.
Usando el mismo código de ejemplo que acabamos de usar anteriormente, implementemos esto.
import unittest
class MyTestCase(unittest.TestCase):
def test_division_by_error(self):
import operator
self.assertRaises(TypeError, operator.floordiv, 55, 0)
if __name__ == "__main__":
unittest.main()
Producción :
E
======================================================================
ERROR: test_division_by_error (__main__.MyTestCase)
----------------------------------------------------------------------
Traceback (most recent call last): File "c:\Users\Neema\Desktop\Article Requirement Spec and Example
Articles\user.py", line 16, in test_division_by_error
self.assertRaises(TypeError, operator.floordiv, 55, 0)
File "C:\Users\Neema\AppData\Local\Programs\Python\Python39\lib\unittest\case.py", line 733, in assertRaises
return context.handle('assertRaises', args, kwargs)
File "C:\Users\Neema\AppData\Local\Programs\Python\Python39\lib\unittest\case.py", line 201, in handle
callable_obj(*args, **kwargs)
ZeroDivisionError: integer division or modulo by zero
----------------------------------------------------------------------
Ran 1 test in 0.031s
FAILED (errors=1)
A partir de la salida, se produce un rastreo de error. Esperamos una excepción ZeroDivisionError cuando dividimos un número por cero. En su lugar, pasamos una excepción TypeError aplicada al realizar una operación aritmética entre diferentes tipos de datos, digamos una cadena y un entero.