Unit testing con Python: realizar tests o pruebas de código Python

Las pruebas en el software son un aspecto importante; pues permiten verificar que nuestro código se ejecuta en la manera que debería y que con cada cambio que hacemos no rompemos otras cosas.

Python provee el framework unittest que realiza pruebas unitarias de nuestro código y tiene varios métodos para realizar pruebas de código.

Pruebas unitarias con Python y el framework unittest
Pruebas unitarias con Python y el framework unittest

Hoy veremos cómo realizar nuestros primeros tests con el framework unittest de Python, que ya viene instalado por defecto.

Instalar Python

Si todavía no has instalado Python o no tienes las nociones básicas te invito a instalarlo en Windows, Linux Ubuntu o incluso en Android.

Documentación de unittest en Python

La documentación oficial se encuentra en el sitio oficial, ahí puedes indagar más sobre el tema. Aquí daré una breve explicación que sentará las bases de las pruebas unitarias en Python.

Escribir funciones

Vamos a escribir algunas funciones que realizan operaciones matemáticas; todo esto para ejemplificar y no confundir al lector con ejemplos complejos.

Tenemos cuatro operaciones que van a sumar, restar, dividir y multiplicar. Las 4 están en el siguiente archivo:

"""
    Vamos a probar estas funciones, puedes importarlas
    como tú quieras. En este caso son simples para
    no confundir al lector

    @author parzibyte
"""


def suma(a, b):
    return a + b


def resta(a, b):
    return a - b


def multiplicacion(a, b):
    return a * b


def division(a, b):
    return a / b

El archivo en sí mismo no está llamándolas, solamente las define. Ahora veamos cómo se pueden probar.

Definir tests unitarios con unittest

Para realizar las pruebas se requiere escribir una clase que extienda de unittest.TestCase. Dentro de esa clase definimos funciones que serán las encargadas de probar otras funciones; una función de prueba debe estar presente por cada función.

"""
    Probar las funciones con unittest

    @author parzibyte
"""
import unittest
# Importamos nuestras funciones, esto puede cambiar de acuerdo a tus necesidades,
# aquí pongo un ejemplo
from main import *


class TestOperaciones(unittest.TestCase):
    def setUp(self):
        # Aquí, opcionalmente, ejecuta lo que deberías ejecutar antes
        # de comenzar cada test.
        pass

    def test_suma(self):
        esperado = 3
        actual = suma(1, 2)
        # Pásalo en el orden: actual, esperado
        self.assertEqual(actual, esperado)

    def test_resta(self):
        esperado = 5
        actual = resta(10, 5)
        # Pásalo en el orden: actual, esperado
        self.assertEqual(actual, esperado)

    def test_multiplicacion(self):
        esperado = 50
        actual = multiplicacion(10, 5)
        # Pásalo en el orden: actual, esperado
        self.assertEqual(actual, esperado)

    def test_division(self):
        esperado = 6
        actual = division(12, 2)
        # Pásalo en el orden: actual, esperado
        self.assertEqual(actual, esperado)

    def tearDown(self):
        # Aquí lo contrario de setUp, cuando cada test ha terminado
        pass


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

En el código fuente vemos que se utiliza assertEqual, esto recibe dos argumentos: el valor real o actual, y el valor esperado.

Los métodos setUp y tearDown son llamados antes de empezar cada test y después de terminar cada test, respectivamente.

Al final hacemos la comprobación de if __name__ == '__main__' para que, si el archivo es ejecutado directamente,los tests sean ejecutados, solo en caso de que el archivo sea ejecutado directamente, no importado.

Probar tests con python

Cuando ya definimos nuestros test, los ejecutamos como un archivo normal de Python así:

python probar.py

Actualmente existe el descubrimiento de tests y cosas de esas pero por ahora veremos lo básico. Recomiendo pasar la opción -v para que muestre más detalles de lo que está pasando:

python probar.py -v

La salida es como se ve a continuación:

Ejecutar pruebas unitarias con Python 3
Ejecutar pruebas unitarias con Python 3

Los 4 tests unitarios fueron pasados. Ahora voy a cambiar el método de la suma (para que devuelva a/b en lugar de a+b) y ejecutar las pruebas de nuevo:

Fallar test en Python - Unittest
Fallar test en Python – Unittest

Nota: olvidé pasar la opción -v pero es lo mismo, el test ha fallado y nos lo está indicando:

AssertionError: 0.5 != 3

Efectivamente, debido a que está devolviendo la división y no la suma los valores de esperado y actual no coinciden.

Otros métodos de assert

No solamente existe assertEqual, también existen los siguientes (he puesto solo algunos):

  • assertNotEqual: lo contrario de assertEqual, asegurarse de que dos valores no son iguales.
  • assertTrue: asegurar que un valor es True
  • assertFalse: asegurar que un valor es False
  • assertRaises: asegurar que se genera una excepción

Todo eso lo encuentras más detallado en los enlaces que he anexado.

Conclusión

No escribas pocos tests, escribe varios. No solamente escribas pruebas “buenas” sino también malas. Por ejemplo, haz tests para probar que se genera una excepción cuando pasas determinados valores.

Prueba todo tu código con distintos escenarios, entre más pruebas unitarias escribas menores errores tendrás en producción.

Aprender más sobre Python.

Estoy aquí para ayudarte 🤝💻


Estoy aquí para ayudarte en todo lo que necesites. Si requieres alguna modificación en lo presentado en este post, deseas asistencia con tu tarea, proyecto o precisas desarrollar un software a medida, no dudes en contactarme. Estoy comprometido a brindarte el apoyo necesario para que logres tus objetivos. Mi correo es parzibyte(arroba)gmail.com, estoy como@parzibyte en Telegram o en mi página de contacto

No te pierdas ninguno de mis posts 🚀🔔

Suscríbete a mi canal de Telegram para recibir una notificación cuando escriba un nuevo tutorial de programación.

1 comentario en “Unit testing con Python: realizar tests o pruebas de código Python”

Dejar un comentario

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