Pruebas de código en Python (A3C34C2D05)

Introducción

Las pruebas son una parte esencial en el proceso de desarrollo de aplicaciones. Gracias a ellas es posible verificar la correcta funcionalidad del código y garantizar su calidad. Un claro ejemplo de su importancia es el caso del Desarrollo Guiado por las Pruebas (TDD).

En este documento, se explorará cómo escribir pruebas unitarias, en concreto para aplicaciones desarrolladas en Python. Antes de continuar, es aconsejable que revises la documentación A3C34C1D06.

DOCUMENTO

PRUEBAS DE CÓDIGO. ASPECTOS FUNDAMENTALES

Documento introductorio a las pruebas de código y el enfoque TDD.

Documento referenciado: A3C34C1D06

Tipos de pruebas. Pruebas unitarias

Las pruebas utilizadas durante el desarrollo de aplicaciones son de diferentes tipos, el uso de unas u otras depende de lo que se quiera verificar con ellas. Algunas de las más utilizadas son: las pruebas unitarias, pruebas de integración, pruebas funcionales y pruebas de regresión. Este documento se centra en las primeras, las pruebas unitarias.

Las pruebas unitarias son un tipo de pruebas focalizadas en verificar el correcto funcionamiento de unidades individuales de código. Es decir, asegurar que funciones, métodos o clases funcionen correctamente de manera aislada.

En Python, existen diferentes herramientas y frameworks que facilitan la creación y ejecución de pruebas unitarias. Algunos de las librerías más utilizados en Python son unittest, pytest y nose.

Pruebas en Python: unittest

Unittest es el framework de pruebas integrado en la biblioteca estándar de Python. Proporciona una serie de módulos y herramientas que ayudan a comprobar las funciones del código y facilitar el desarrollo de las aplicaciones.

Ejemplo práctico

En esta sección se verá un ejemplo práctico de pruebas unitarias con Python. En concreto, se ha desarrollado una aplicación que funciona a modo de calculadora. Se trata de una clase en la que se han implementado los métodos de suma, resta, multiplicación y división:

class Calculadora:
    def suma(self, a, b):
        return a + b
    def resta(self, a, b):
        return a - b
    def multiplicacion(self, a, b):
        return a * b
    def division (self, a, b):
        if b == 0:
            raise ValueError(“Error: no se puede dividir entre cero”)
        return a / b

Antes de implementar las pruebas, hay que analizar los diferentes escenarios a probar. Por ejemplo, en el caso de la calculadora será necesario comprobar la suma de dos números positivos, la resta de dos números negativos, la división entre cero, etc.

Una vez estudiados los casos a implementar, se procede a su codificación. En este caso, con unnitest, se pueden seguir los siguientes pasos:

  • Crear una clase de pruebas llamada TestCalculadora que hereda de unittest.TestCase.
  • Importar el módulo a probar (Calculadora).
  • Crear el método setUp para inicializar una instancia de la calculadora antes de cada prueba.
  • Definir métodos de prueba que cubran distintas posibilidades de ejecución. En cada método se emplearán aserciones como “assertEquals”, “assertNoEquals”, “assertTrue” o “assertFalse” para comprobar la funcionalidad.
  • El nombre de los métodos debe comenzar con “test_”.

Este código muestra un ejemplo de pruebas unitarias para cubrir la clase Calculadora.

import unittest
from Calculadora import Calculadora
class TestCalculadora(unittest.TestCase):
    def setUp(self):
        self.calculadora = Calculadora()

    def test_suma(self):
        result = self.calculadora.suma(-1, 3)
        self.assertEqual(result, 2)

    def test_subtraction(self):
        result = self.calculadora.resta(10, 4)
        self.assertFalse(result!= 6

    def test_multiplication(self):
        result = self.calculadora.multiplicacion(0, 5)
        self.assertTrue(result == 0)

    def test_division(self):
        result = self.calculadora.division(80, 10)
        self.assertNotEqual(result, 80)

if __name__ == ‘__main__’:
    unittest.main()

En este caso se ha implementado una prueba unitaria por cada método de la clase Calculadora. Sin embargo, lo correcto sería cubrir los diferentes escenarios de ejecución que puede tener cada uno de ellos.

En resumen, en este documento se ha abordado la importancia de las pruebas en el desarrollo de aplicaciones. En particular, se ha visto un ejemplo práctico de creación de pruebas unitarias con el framework de la librería estándar de Python, unittest. Es importante tener en cuenta que el mundo de las pruebas es amplio y complejo, y las pruebas unitarias son solo una parte del panorama completo de las pruebas de software.

Nota

Para agilizar la creación y comprobación de pruebas unitarias, es recomendable utilizar algunos de los IDEs que dan soporte a Python. Puesto que en temas anteriores se vio el entorno de Visual Studio Code, es interesante ampliar los conocimientos utilizando las librerías de pruebas de Python que pueden ser utilizadas desde el IDE.

Saber más

A continuación, se listan algunos dos de los principales frameworks de pruebas para aplicaciones desarrolladas en Python.