Saltar al contenido principal

Tutorial de Pruebas Unitarias en Python

Aprende qué son las pruebas unitarias, por qué son importantes y cómo puedes implementarlas con la ayuda de Python.
Actualizado 16 mar 2025  · 10 min de lectura

Las pruebas unitarias son un método de prueba de software mediante el cual se someten unidades individuales de código fuente a diversas pruebas para determinar si son aptas para su uso. Determina y constata la calidad de tu código.

Por lo general, cuando finaliza el proceso de desarrollo, el desarrollador codifica los criterios, o los resultados que se sabe que son potencialmente prácticos y útiles, en el script de prueba para verificar la corrección de una unidad concreta. Durante la ejecución de los casos de prueba, varios marcos registran las pruebas que fallan algún criterio e informan de ellas en un resumen.

Se espera que los desarrolladores escriban guiones de prueba automatizados, que garanticen que todas y cada una de las secciones o unidades cumplen su diseño y se comportan como se espera de ellas.

Pruebas unitarias en Python

Aunque escribir pruebas manuales para tu código es sin duda una tarea tediosa y que lleva mucho tiempo, el marco de pruebas unitarias incorporado en Python te ha facilitado mucho la vida.

El marco de pruebas unitarias en Python se llama unittest y viene empaquetado con Python.

Las pruebas unitarias hacen que tu código esté preparado para el futuro, ya que anticipas los casos en los que tu código podría fallar o producir un error. Aunque no puedas prever todos los casos, aborda la mayoría de ellos.

Una unidad puede dividirse en varias categorías:

  • Un módulo entero,
  • Una función individual,
  • Una interfaz completa como una clase o un método.

La mejor forma de escribir pruebas unitarias para tu código es empezar primero con la unidad comprobable más pequeña que pueda tener tu código, luego pasar a otras unidades y ver cómo esa unidad más pequeña interactúa con otras unidades, de esta forma podrías construir una prueba unitaria completa para tus aplicaciones.

El marco de pruebas unitarias de Python se inspiró en JUnit de Java y tiene características similares a los principales marcos de pruebas unitarias de otros lenguajes. El marco de pruebas unitarias de Python ofrece varias funcionesentre las que se incluyen

  • Automatización de pruebas
  • Compartir el código de configuración y apagado para las pruebas
  • Agregar pruebas en colecciones
  • Independencia de las pruebas del marco de información

Ahora vamos a poner un ejemplo y entender por qué necesitas tener pruebas unitarias de tu código.

Primeros pasos con unittest de Python

A continuación, te indicamos los pasos necesarios para utilizar el framework unittest de Python.

Crear una función cubo

Escribamos un código para calcular el volumen de un cubo en Python

def cuboid_volume(l):
    return (l*l*l)
length = [2,1.1, -2.5, 2j, 'two']
for i in range(len(length)):
    print ("The volume of cuboid:",cuboid_volume(length[i]))
The volume of cuboid: 8
The volume of cuboid: 1.3310000000000004
The volume of cuboid: -15.625
The volume of cuboid: (-0-8j)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-7-67e1c37a435f> in <module>
      1 for i in range(len(length)):
----> 2     print ("The volume of cuboid:",cuboid_volume(length[i]))
<ipython-input-2-f50464fd88da> in cuboid_volume(l)
      1 def cuboid_volume(l):
----> 2     return (l*l*l)
TypeError: can't multiply sequence by non-int of type 'str'

Análisis de resultados

El resultado anterior debería darte alguna intuición sobre la importancia de disponer de una prueba unitaria para tu código. Ahora bien, hay tres cosas que son ciertamente incorrectas en el código anterior:

  • En primer lugar, el volumen del cuboide es negativo,
  • En segundo lugar, el volumen del cuboide es un número complejo,
  • Por último, el código que resulta es un TypeError ya que no se puede multiplicar una cadena, que es un no-int.

Afortunadamente, el tercer problema dio error, mientras que el primero y el segundo se resolvieron aunque el volumen del cuboide no puede ser negativo ni un número complejo.

Las pruebas unitarias suelen escribirse como código independiente en un archivo distinto, y puede haber distintas convenciones de nomenclatura que podrías seguir. Puedes escribir el nombre del archivo de pruebas unitarias como name of the code/unit + test separado por un guión bajo o test + name of the code/unit separado por un guión bajo.

Por ejemplo, supongamos que el nombre del archivo de código anterior es cuboid_volume.py, entonces el nombre del código de tu prueba unitaria podría ser cuboid_volume_test.py

Sin más preámbulos, vamos a escribir la prueba unitaria del código anterior.

Utilizar assertAlmostEqual

En primer lugar, vamos a crear un archivo python con el nombre volume_cuboid.py, que tendrá el código para calcular el volumen y en segundo lugar con el nombre test_volume_cuboid.py, que tendrá el código de pruebas unitarias.

importa unittest

La clase TestCuboid hereda el módulo unittest, y en esta clase definirías varios métodos que querrías que tu prueba unitaria comprobara con tu función cuboid_volume.

La primera función que definirás es test_volume, que comprobará si la salida que da tu cuboid_volume es igual a la que esperas. Para ello, utilizarás el método assertAlmostEqual.

Prueba 1

class TestCuboid(unittest.TestCase):
    def test_volume(self):
        self.assertAlmostEqual(cuboid_volume(2),8)
        self.assertAlmostEqual(cuboid_volume(1),1)
        self.assertAlmostEqual(cuboid_volume(0),0)
        self.assertAlmostEqual(cuboid_volume(5.5),166.375)

código 1

código 2

Vamos a ejecutar el script anterior. Ejecutarías el módulo unittest como un script especificando -m mientras lo ejecutas.

!python -m unittest test_volume_cuboid.py

Salida:

.
----------------------------------------------------------------------
Ran 1 test in 0.000s
OK

¡Estupendo! Así que has conseguido que funcione tu primer código de prueba unitario.

La prueba se ejecutó correctamente y devolvió, OK, lo que significa que la función cuboide_volumen funciona como cabría esperar.

Prueba 2

Veamos qué ocurre cuando falla uno de los métodos de assertAlmostEqual.

código 3

Observa que se ha modificado la última afirmación.

!python -m unittest test_volume_cuboid.py

Salida:

F
======================================================================
FAIL: test_volume (test_volume_cuboid.TestCuboid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\hda3kor\Documents\Unit_Testing_Python\test_volume_cuboid.py", line 15, in test_volume
    self.assertAlmostEqual(cuboid_volume(5.5),0)
AssertionError: 166.375 != 0 within 7 places (166.375 difference)
----------------------------------------------------------------------
Ran 1 test in 0.001s
FAILED (failures=1)

Pues bien, a partir de la salida anterior, puedes observar que la última sentencia assert dio como resultado un AssertionError, por lo tanto un fallo de la prueba unitaria. El módulo de pruebas unitarias de Python te muestra el motivo del fallo, junto con el número de fallos que tiene tu código.

Utilizar assertRaises

Ahora vamos a explorar otro método assert, es decir, assertRaises, que te ayudará a averiguar si tu función cuboid_volume maneja correctamente los valores de entrada.

Supongamos que quieres comprobar si tu función cuboid_volume maneja la clase o tipo de entrada, por ejemplo, si pasas una cadena como entrada, la manejará como una excepción o con una condición if, ya que la longitud del cuboide nunca puede ser una cadena.

código 4

!python -m unittest test_volume_cuboid.py

Salida:

F.
======================================================================
FAIL: test_input_value (test_volume_cuboid.TestCuboid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "C:\Users\hda3kor\Documents\Unit_Testing_Python\test_volume_cuboid.py", line 17, in test_input_value
    self.assertRaises(TypeError, cuboid_volume, True)
AssertionError: TypeError not raised by cuboid_volume
----------------------------------------------------------------------
Ran 2 tests in 0.001s
FAILED (failures=1)

¡Estupendo! Por lo tanto, a partir de la salida anterior, es evidente que tu código volume_cuboid.py no se ocupa correctamente de la entrada que se le pasa.

Modificar la función cubo

Vamos a añadir una condición en el volume_cuboid.py para comprobar si la entrada o la longitud del cuboide es un booleano o una cadena y lanzar un error.

código 5

!python -m unittest test_volume_cuboid.py

Salida:

..
----------------------------------------------------------------------
Ran 2 tests in 0.001s
OK

Ejecutar el script de pruebas de Python en el laboratorio Jupyter

Ahora vamos a ejecutar el script de prueba dentro del laboratorio jupyter. Para conseguirlo, primero definirías el script de prueba en el laboratorio jupyter, como se muestra a continuación.

# -*- coding: utf-8 -*-
"""
Created on Sat Apr 25 20:16:58 2020
@author: Aditya
"""
from volume_cuboid import *
import unittest
class TestCuboid(unittest.TestCase):
    def test_volume(self):
        self.assertAlmostEqual(cuboid_volume(2),8)
        self.assertAlmostEqual(cuboid_volume(1),1)
        self.assertAlmostEqual(cuboid_volume(0),1)
    def test_input_value(self):
        self.assertRaises(TypeError, cuboid_volume, True)

A continuación, utilizarás el método unittest.main() para ejecutar el script de prueba, puedes pasar varios argumentos al método siguiente, de los cuales uno es verbosity level.

Experimentemos con distintos niveles de verbosidad y veamos cómo cambia la descripción de salida.

Verbosidad 0

unittest.main(argv=[''],verbosity=0, exit=False)
Output:
----------------------------------------------------------------------
Ran 2 tests in 0.000s
OK
<unittest.main.TestProgram at 0x1de02774348>

Verbosidad 1

unittest.main(argv=[''],verbosity=1, exit=False)
Output:
..
----------------------------------------------------------------------
Ran 2 tests in 0.002s
OK
<unittest.main.TestProgram at 0x1de027a1cc8>

Verbosidad 2

unittest.main(argv=[''],verbosity=2, exit=False)
Output:
test_input_value (__main__.TestCuboid) ... ok
test_volume (__main__.TestCuboid) ... ok
----------------------------------------------------------------------
Ran 2 tests in 0.002s
OK
<unittest.main.TestProgram at 0x1de027a8308>

Visualizar el error de aserción

Por último, modifiquemos el assertAlmostEqual final en el método test_volume y analicemos cómo el nivel de verbosidad 2 mostrará el fallo del método.

# -*- coding: utf-8 -*-
"""
Created on Sat Apr 25 20:16:58 2020
@author: Aditya
"""
from volume_cuboid import *
import unittest
class TestCuboid(unittest.TestCase):
    def test_volume(self):
        self.assertAlmostEqual(cuboid_volume(2),8)
        self.assertAlmostEqual(cuboid_volume(1),1)
        self.assertAlmostEqual(cuboid_volume(0),1)
    def test_input_value(self):
        self.assertRaises(TypeError, cuboid_volume, True)
unittest.main(argv=[''],verbosity=2, exit=False)

Salida:

test_input_value (__main__.TestCuboid) ... ok
test_volume (__main__.TestCuboid) ... FAIL
======================================================================
FAIL: test_volume (__main__.TestCuboid)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "<ipython-input-28-46ad33b909ee>", line 14, in test_volume
    self.assertAlmostEqual(cuboid_volume(0),1)
AssertionError: 0 != 1 within 7 places (1 difference)
----------------------------------------------------------------------
Ran 2 tests in 0.003s
FAILED (failures=1)
<unittest.main.TestProgram at 0x1de027b5448>

Resumen

De los resultados anteriores pueden extraerse las siguientes conclusiones:

  • El nivel de verbosidad 0 sólo muestra cuántas pruebas se ejecutaron, es decir, 2 pruebas junto con el tiempo que se tardó en ejecutarlas,
  • Verbosidad nivel 1 añade dos puntos .. que significa que se han ejecutado dos pruebas,
  • El nivel de verbosidad 2 muestra los nombres detallados de los métodos que se ejecutaron junto con su estado OK o FAIL.

Métodos disponibles de unittest Assert

Hay muchos métodos de afirmación en el módulo de pruebas unitarias de Python, que podrías aprovechar para tus pruebas.

Métodos de afirmación utilizados habitualmente

Métodos de afirmación utilizados habitualmente

Fuente: documentación de unittest

 Controles de producción

Utilizando los siguientes métodos, puedes comprobar la producción de excepciones, advertencias y mensajes de registro.

Controles de producción

Fuente: documentación de unittest

 Métodos para tareas específicas

Métodos específicos de la tarea

Fuente: documentación de unittest

 

Para conocer en detalle los métodos de assert, consulta la documentación oficial de Python de Python.

También puedes conocerlos con ayuda del módulo Pydoc, que es similar a una función help en Python. A continuación se muestra una demostración de cómo podrías utilizar el módulo Pydoc para leer la documentación del método assertCountEqual.

!python -m pydoc unittest.TestCase.assertCountEqual

Salida:

Help on function assertCountEqual in unittest.TestCase:
unittest.TestCase.assertCountEqual = assertCountEqual(self, first, second, msg=None)
    An unordered sequence comparison asserting that the same elements,
    regardless of order.  If the same element occurs more than once,
    it verifies that the elements occur the same number of times.
        self.assertEqual(Counter(list(first)),
                         Counter(list(second)))
     Example:
        - [0, 1, 1] and [1, 0, 1] compare equal.
        - [0, 0, 1] and [0, 1] compare unequal.

Conclusión

Este tutorial fue una introducción básica a las pruebas unitarias en python y su importancia como desarrollador. Un buen ejercicio para ti sería escribir un módulo de pruebas unitarias para cualquiera de tus proyectos anteriores. Esto te dará una buena experiencia práctica en la escritura de pruebas unitarias. Además, prueba a explorar el resto de métodos Assert. Puedes leer más sobre las pruebas unitarias con nuestro tutorial de Pytest.

Si te estás iniciando en Python y quieres aprender más, sigue nuestro curso de Introducción a la Ciencia de Datos en Python en Python.

Conviértete en Desarrollador Python

Adquiere los conocimientos de programación que necesitan todos los desarrolladores de Python.
Empieza a aprender gratis

Abid Ali Awan's photo
Author
Abid Ali Awan
LinkedIn
Twitter

Soy un científico de datos certificado que disfruta creando aplicaciones de aprendizaje automático y escribiendo blogs sobre ciencia de datos. Actualmente me centro en la creación de contenidos, la edición y el trabajo con grandes modelos lingüísticos.

Temas

¡Aprende más sobre Python con estos cursos!

Curso

Introduction to Python

4 hr
6.1M
Master the basics of data analysis with Python in just four hours. This online course will introduce the Python interface and explore popular packages.
Ver detallesRight Arrow
Comienza el curso
Ver másRight Arrow
Relacionado
Machine Learning Jobs Header

Tutorial

Cómo utilizar Pytest para pruebas unitarias

Explore qué es Pytest y para qué se utiliza mientras lo compara con otros métodos de prueba de software.
Kurtis Pykes 's photo

Kurtis Pykes

13 min

Tutorial

Tutorial de Python sobre conjuntos y teoría de conjuntos

Aprende sobre los conjuntos en Python: qué son, cómo crearlos, cuándo usarlos, funciones incorporadas y su relación con las operaciones de la teoría de conjuntos.
DataCamp Team's photo

DataCamp Team

13 min

Tutorial

Tutorial de funciones de Python

Un tutorial sobre funciones en Python que cubre cómo escribir funciones, cómo invocarlas y mucho más.
Karlijn Willems's photo

Karlijn Willems

14 min

Tutorial

Tutorial Python Docstrings : Ejemplos y Formato de Cadenas Doc Pydoc, Numpy, Sphinx

Aprende sobre las Docstrings de Python. Encuentra diferentes ejemplos y tipos de formato de docstrings para Sphinx, Numpy y Pydoc.
Aditya Sharma's photo

Aditya Sharma

15 min

Tutorial

Tutorial sobre cómo ejecutar scripts en Python

Aprenda cómo puede ejecutar un script Python desde la línea de comandos, y también cómo puede proporcionar argumentos de línea de comandos a su script.
Aditya Sharma's photo

Aditya Sharma

10 min

Ver másVer más