- 1 - Test Unitarios en Python Unittest y Pytest
- 2 - Test Unitarios en Python con Pytest
- 3 - Instalación de Pytest
- 4 - Test unitarios para varias funciones
- 5 - Test Unitarios con Unittest
- 6 - Métodos de aserción en Unittest
- 7 - Limitaciones en los test unitarios
- 8 - Conclusión
Test Unitarios en Python Unittest y Pytest
EN programación, la realización de un test unitario es el proceso por el que podemos comprobar el correcto funcionamiento de un fragmento de código o de la totalidad de una apliación. Cuando implementamos un conjunto de pruebas unitarias sobre nuestro código, hemos de comprobar que se cumplan los siguientes requisitos:
- Automatizable: Una vez implementado el conjunto de test unitarios, estos deben de tener la capacidad se ejecutarse y validadarse por si mismos, sin necesidad de una intervención manual del progrmador.
- Completas: Estos test deben cubrir la mayor cantidad posible de código desarrollado.
- Reutilizable: Deben ser ejecutables una y otra vez, sin que su resultado dependa de factores externos.
- Independientes: Cada test unitario debe ser independiente del resto, de forma que la ejecución de uno no afecte al resultado de otro.
- Profesionales: DEben ser desarrollados en conciencia y con la misma profesionalizadd con la que ha sido desarrollado el resto del código.
Test Unitarios en Python con Pytest
Si has estado dentro del mundo de Python, seguramente hayas oído de bastantes librerías que tiene para resolver distintos problemas de distintas índoles. Es por ello que también cuenta con algunas librerías diseñadas para realizar test unitarios. Ahora vamos a ver una de las herramientas más populares para realizar test unitarios en Python: Pytest.
Con la utilización de Pytest, podemos realizar estos test unitarios de una forma más sencilla y cómoda que realizar nosotros mismos esas pruebas con un código creado por nosotros. Ahora vamos a ver como tenemos que trabajar y cómo podemos crear nuestros propios test unitarios con Pytest.
Instalación de Pytest
Para instalar Pytest, simplemente tenemos que ejecutar el siguiente comando en nuestra terminal:
pip install pytest
O bien si eres como yo y usas uv la instalación sería:
uv add pytest
Una forma que tenemos para la revisión de que se ha instalado correctamente es ejecutar el siguiente comando:
pytest --version
Ahora que ya lo tenemos instalado podemos empezar a crear nuestros test unitarios. Así que en primer lugar vamos a crear un archivo que llamaremos test_prueba.py y en este crearemos un test unitario para comprobar si la suma de dos números enteros se realiza correctamente.
import pytest
def test_suma_enteros():
x = 3
y = 5
resultado = 6
assert x+y == resultado
Ahora es cuando tenemos que ejecutar el siguiente código de la siguiente manera.
pytest test_prueba.py
En este caso veremos que hay un error, ya que el resultado de la suma de 3 + 5 no es 6. Por lo tanto, tenemos que cambiar el valor de la variable resultado a 8 para que el test unitario pase correctamente.
import pytest
def test_suma_enteros():
x = 3
y = 5
resultado = 8
assert x+y == resultado
Ahora si volvemos a ejecutar el comando pytest test_prueba.py, veremos que el test unitario pasa correctamente.
Test unitarios para varias funciones
Antes hemos visto como hacer un test unitario de una función, pero es posible que necesitemos hacer un test para varias funciones. Ahora vamos a imaginar que tenemos un código en el que dentro nos encontramos con varias funciones que serían un conjunto de operadores matemáticos básicos. Estas funciones serían las siguientes:
def suma(x, y):
return x + y
def resta(x, y):
return x - y
def multiplicacion(x, y):
return x * y
def division(x, y):
if y == 0:
raise ValueError("No se puede dividir por cero")
return x / y
Ahora podemos crear un archivo llamado test_operaciones.py en el que vamos a crear los test unitarios para cada una de estas funciones.
import pytest
from operaciones import suma, resta, multiplicacion, division
def test_suma():
assert suma(3, 5) == 8
assert suma(-1, 1) == 0
assert suma(0, 0) == 0
def test_resta():
assert resta(5, 3) == 2
assert resta(-1, 1) == -2
assert resta(0, 0) == 0
def test_multiplicacion():
assert multiplicacion(3, 5) == 15
assert multiplicacion(-1, 1) == -1
assert multiplicacion(0, 10) == 0
def test_division():
assert division(10, 2) == 5
assert division(-10, 2) == -5
assert division(0, 1) == 0
with pytest.raises(ValueError):
division(10, 0)
En este caso, hemos creado un test unitario para cada una de las funciones que hemos definido anteriormente. Cada test unitario comprueba diferentes casos para asegurarse de que las funciones funcionan correctamente. Ahora podemos ejecutar el comando pytest test_operaciones.py para comprobar que todos los test unitarios pasan correctamente.
Test Unitarios con Unittest
Otra de las librerías que podemos utilizar para realizar test unitarios en Python es Unittest. Esta librería viene incluida en la biblioteca estándar de Python, por lo que no es necesario instalar nada adicional para utilizarla.
Unittest nos va a ofrecer tres tipos de salidas,:
- OK: Indica que la prueba ha sido ejecutada correctamente y no se ha encontrado ningún error.
- FAIL: Indica que la prueba ha fallado debido a una aserción y que es necesario revisar el código para corregir el error. Además sería interesante incluir una excepción que nos indique el motivo del fallo (
try/except). - ERROR: Indica que se ha producido un error durante la ejecución y no ha pasado la prueba.
Debemos comprobar que tenemos la librería unittest2 instalada. Si no la tenemos, podemos instalarla utilizando el siguiente comando:
pip install unittest2
O bien si usas uv:
uv add unittest2
Ahora vamos a ver un ejemplo de cómo utilizar Unittest para crear un test unitario para una función que suma dos números enteros.
import unittest
def suma(x, y):
return x + y
class TestSuma(unittest.TestCase):
def test_suma(self):
self.assertEqual(suma(3, 5), 8)
self.assertEqual(suma(-1, 1), 0)
self.assertEqual(suma(0, 0), 0)
if __name__ == '__main__':
unittest.main()
Una vez que lo ejecutemos veremos en la terminal que todos los test unitarios han pasado correctamente. Cómo puedes ver la gran diferencia entre las herramientas que hemos visto para realizar test unitarios en Python es la forma en la que se escriben los test unitarios. Ambas herramientas son muy útiles y nos permiten realizar test unitarios de una forma sencilla y cómoda. Las diferencias que tenemos son:
- Implementar una clase que herede de la clase unittest.TestCase.
- NNecesitamos utilizar la palabra clave reservada
assertEqualpara comprobar que el resultado de nuestra función implementada devuelve el resultado correcto.
Métodos de aserción en Unittest
Unittest proporciona varios métodos de aserción que podemos utilizar para verificar diferentes condiciones en nuestros test unitarios. Algunos de los métodos de aserción más comunes son:
| Método de Aserción | Checks |
|---|---|
| assertEqual(a, b) | Verifica que a y b son iguales. |
| assertNotEqual(a, b) | Verifica que a y b son diferentes. |
| assertTrue(x) | Verifica que x es True. |
| assertFalse(x) | Verifica que x es False. |
| assertIs(a, b) | Verifica que a es b. |
| assertIsNone(x) | Verifica que x es None. |
| assertIsNotNone(a) | Verifica que a no es None. |
| assertIn(a, b) | Verifica que a está en b. |
| assertIsInstance(a, b) | Verifica que a es una instancia de b. |
| assertIsNotInstance(a, b) | Verifica que a no es una instancia de b. |
Estos métodos de aserción nos permiten verificar diferentes condiciones en nuestros test unitarios y asegurarnos de que nuestro código funciona correctamente.
Otros de los métodos que podemos encontrar en Unittest son:
| Método | Descripción |
|---|---|
| assertAlmostEqual(a, b) | Verifica que a y b son aproximadamente iguales. |
| assertNoAlmostEqual(a, b) | Verifica que a y b no son aproximadamente iguales. |
| assertGreater(a, b) | Verifica que a es mayor que b. |
| assertGreaterEqual(a, b) | Verifica que a es mayor o igual que b. |
| assertLess(a, b) | Verifica que a es menor que b. |
| assertLessEqual(a, b) | Verifica que a es menor o igual que b. |
| assertRegex(s, r) | Verifica que la cadena s coincide con la expresión regular r. |
| assertNotRegex(s, r) | Verifica que la cadena s no coincide con la expresión regular r. |
| assertCountEqual(a, b) | Verifica que a y b contienen los mismos elementos, sin importar el orden. |
Estos métodos adicionales nos permiten realizar verificaciones más específicas en nuestros test unitarios y asegurarnos de que nuestro código funciona correctamente en diferentes situaciones.
| Método | Descripción |
|---|---|
| assertMultiLineEqual(a, b) | Verifica que las cadenas a y b son iguales, línea por línea. |
| assertSequenceEqual(a, b) | Verifica que las secuencias a y b son iguales. |
| assertListEqual(a, b) | Verifica que las listas a y |
| assertListEqual(a, b) | Verifica que las listas a y b son iguales. |
| assertTupleEqual(a, b) | Verifica que las tuplas a y b son iguales. |
| assertSetEqual(a, b) | Verifica que los conjuntos a y b son iguales. |
| assertDictEqual(a, b) | Verifica que los diccionarios a y b son iguales. |
Limitaciones en los test unitarios
Hay pruebas que serían complejas de hacer, como por ejemplo:
- Pruebas que dependan de la interfaz gráfica de usuario (GUI).
- Pruebas que requieran interacción con hardware específico.
- Pruebas que dependan de servicios externos o APIs.
- Pruebas que involucren condiciones de carrera o concurrencia.
- Pruebas que requieran un entorno específico o configuración compleja.
- Pruebas que dependan de datos dinámicos o en tiempo real.
- Pruebas que involucren algoritmos complejos o cálculos matemáticos avanzados.
Por jemplo, si tenemos que hacer una prueba a un generador de números aleatorios y si no salen los mismos números, no podemos simular cada uno de los casos posibles con cada uno de los números que tenemos, ahí lo más conveniente sería probar que ocurre cuando se acierta o no se acierta un número, pero no probar con todos los números posibles.
Conclusión
En conclusión, las pruebas unitarias son una parte fundamental del desarrollo de software y nos permiten asegurar la calidad y funcionalidad de nuestro código. En Python, tenemos varias herramientas disponibles para implementar pruebas unitarias, siendo Pytest y Unittest dos de las más populares. Ambas herramientas nos ofrecen diferentes enfoques y características para crear y ejecutar pruebas unitarias de manera efectiva. Al elegir entre Pytest y Unittest, es importante considerar las necesidades específicas de nuestro proyecto y el equipo de desarrollo. Independientemente de la herramienta que elijamos, lo más importante es adoptar una cultura de pruebas unitarias en nuestro proceso de desarrollo para garantizar la calidad y confiabilidad de nuestro código.
¿Listo para hacer crecer tu negocio?
Analicemos tu proyecto y definamos la estrategia perfecta para alcanzar tus objetivos
Solicitar consultoría gratuita