Escribiendo pruebas unitarias con unittest
1. Introducción a unittest
unittest
es un módulo estándar de Python para la creación y ejecución de pruebas unitarias. Está inspirado en JUnit, un popular framework de pruebas para Java.
2. Estructura Básica
Una prueba unitaria en unittest
se organiza en clases que heredan de unittest.TestCase
. Cada método dentro de esta clase que comience con la palabra test
se considerará una prueba.
3. Ejemplo Básico
Supongamos que tienes una función en un archivo llamado math_functions.py
que deseas probar:
# math_functions.py
def suma(a, b):
return a + b
Ahora, queremos escribir pruebas unitarias para esta función. Creamos un nuevo archivo llamado test_math_functions.py
:
# test_math_functions.py
import unittest
from math_functions import suma
class TestMathFunctions(unittest.TestCase):
def test_suma(self):
self.assertEqual(suma(1, 2), 3)
self.assertEqual(suma(-1, 1), 0)
self.assertEqual(suma(-1, -1), -2)
if __name__ == '__main__':
unittest.main()
4. Detalle de los Componentes
- Importaciones: Importamos
unittest
y la funciónsuma
que vamos a probar. - Clase de Prueba: Definimos
TestMathFunctions
que hereda deunittest.TestCase
. - Métodos de Prueba:
test_suma
es un método de prueba. Utilizamos varios métodos deunittest.TestCase
para verificar el comportamiento esperado, comoassertEqual
. - main():
unittest.main()
ejecuta todas las pruebas cuando el script se ejecuta directamente.
5. Métodos de Assertion
unittest.TestCase
proporciona muchos métodos para verificar los resultados:
assertEqual(a, b)
: Verifica quea
yb
sean iguales.assertNotEqual(a, b)
: Verifica quea
yb
no sean iguales.assertTrue(x)
: Verifica quex
seaTrue
.assertFalse(x)
: Verifica quex
seaFalse
.assertIs(a, b)
: Verifica quea
yb
sean el mismo objeto.assertIsNot(a, b)
: Verifica quea
yb
no sean el mismo objeto.assertIsNone(x)
: Verifica quex
seaNone
.assertIsNotNone(x)
: Verifica quex
no seaNone
.assertIn(a, b)
: Verifica quea
esté enb
.assertNotIn(a, b)
: Verifica quea
no esté enb
.assertRaises(exception, func, *args, **kwds)
: Verifica que se lance una excepción específica.
6. Setup y Teardown
A veces, necesitas preparar el entorno antes de ejecutar cada prueba o limpiarlo después. unittest
proporciona los métodos setUp()
y tearDown()
para este propósito:
import unittest
from math_functions import suma
class TestMathFunctions(unittest.TestCase):
def setUp(self):
# Código para preparar el entorno antes de cada prueba
self.a = 1
self.b = 2
def tearDown(self):
# Código para limpiar después de cada prueba
pass
def test_suma(self):
result = suma(self.a, self.b)
self.assertEqual(result, 3)
if __name__ == '__main__':
unittest.main()
7. Agrupación de Pruebas
Puedes agrupar varias pruebas en un "test suite" y ejecutarlas juntas:
import unittest
from test_math_functions import TestMathFunctions
def suite():
suite = unittest.TestSuite()
suite.addTest(TestMathFunctions('test_suma'))
return suite
if __name__ == '__main__':
runner = unittest.TextTestRunner()
runner.run(suite())
8. Ejecución de las Pruebas
Para ejecutar las pruebas, puedes usar la línea de comandos:
python -m unittest test_math_functions
O simplemente ejecutar el script si contiene unittest.main()
:
python test_math_functions.py
9. Pruebas de Casos Especiales y Excepciones
Es importante también probar cómo tu código maneja casos especiales y excepciones. Por ejemplo:
def division(a, b):
if b == 0:
raise ValueError("División por cero")
return a / b
class TestMathFunctions(unittest.TestCase):
def test_division(self):
self.assertEqual(division(4, 2), 2)
self.assertRaises(ValueError, division, 4, 0)
if __name__ == '__main__':
unittest.main()