El Desarrollo Guiado por Pruebas (TDD, por sus siglas en inglés) es una metodología de desarrollo de software que se centra en escribir pruebas antes de escribir el código funcional. Este enfoque ayuda a garantizar que el código sea robusto, mantenible y cumpla con los requisitos especificados.

Conceptos Clave de TDD

  1. Red-Green-Refactor: Es el ciclo básico de TDD.

    • Red: Escribir una prueba que falle.
    • Green: Escribir el código mínimo necesario para que la prueba pase.
    • Refactor: Mejorar el código manteniendo las pruebas en verde.
  2. Pruebas Unitarias: Son pruebas que verifican el comportamiento de unidades individuales de código, como funciones o métodos.

  3. Cobertura de Pruebas: Es una métrica que indica el porcentaje de código que está cubierto por las pruebas.

  4. Mocking: Es una técnica para simular el comportamiento de objetos complejos o externos en las pruebas.

Ventajas del TDD

  • Mejora la calidad del código: Al escribir pruebas primero, se asegura que el código cumple con los requisitos desde el principio.
  • Facilita el mantenimiento: Las pruebas actúan como documentación viva del código.
  • Reduce errores: Detecta errores en etapas tempranas del desarrollo.

Ejemplo Práctico de TDD

Vamos a desarrollar una función simple que calcule el factorial de un número utilizando TDD.

Paso 1: Escribir una Prueba que Falla (Red)

Primero, escribimos una prueba para una función factorial que aún no existe.

import unittest

class TestFactorial(unittest.TestCase):
    def test_factorial_of_zero(self):
        self.assertEqual(factorial(0), 1)

    def test_factorial_of_positive_number(self):
        self.assertEqual(factorial(5), 120)

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

Al ejecutar esta prueba, obtendremos un error porque la función factorial no está definida.

Paso 2: Escribir el Código Mínimo para Pasar la Prueba (Green)

Ahora, definimos la función factorial para que pase la prueba.

def factorial(n):
    if n == 0:
        return 1
    else:
        result = 1
        for i in range(1, n + 1):
            result *= i
        return result

Paso 3: Refactorizar el Código

Revisamos el código para mejorar su claridad y eficiencia sin romper las pruebas.

def factorial(n):
    if n == 0:
        return 1
    result = 1
    for i in range(1, n + 1):
        result *= i
    return result

En este caso, el código ya es bastante claro y eficiente, por lo que no es necesario realizar más cambios.

Ejercicios Prácticos

  1. Ejercicio 1: Escribir pruebas para una función que determine si un número es primo.

    • Prueba: test_is_prime
    • Función: is_prime
  2. Ejercicio 2: Escribir pruebas para una función que invierta una cadena.

    • Prueba: test_reverse_string
    • Función: reverse_string

Soluciones

Ejercicio 1: Determinar si un número es primo

import unittest

def is_prime(n):
    if n <= 1:
        return False
    for i in range(2, int(n**0.5) + 1):
        if n % i == 0:
            return False
    return True

class TestIsPrime(unittest.TestCase):
    def test_is_prime(self):
        self.assertTrue(is_prime(5))
        self.assertFalse(is_prime(4))
        self.assertTrue(is_prime(13))
        self.assertFalse(is_prime(1))

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

Ejercicio 2: Invertir una cadena

import unittest

def reverse_string(s):
    return s[::-1]

class TestReverseString(unittest.TestCase):
    def test_reverse_string(self):
        self.assertEqual(reverse_string("hello"), "olleh")
        self.assertEqual(reverse_string("world"), "dlrow")
        self.assertEqual(reverse_string(""), "")
        self.assertEqual(reverse_string("a"), "a")

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

Conclusión

El Desarrollo Guiado por Pruebas es una metodología poderosa que puede mejorar significativamente la calidad y mantenibilidad del código. Al seguir el ciclo Red-Green-Refactor, los desarrolladores pueden asegurarse de que su código cumple con los requisitos y es robusto frente a cambios futuros. Practicar TDD regularmente puede ayudar a internalizar estos beneficios y hacer que el proceso de desarrollo sea más eficiente y menos propenso a errores.

Curso de Programación en Python

Módulo 1: Introducción a Python

Módulo 2: Estructuras de Control

Módulo 3: Funciones y Módulos

Módulo 4: Estructuras de Datos

Módulo 5: Programación Orientada a Objetos

Módulo 6: Manejo de Archivos

Módulo 7: Manejo de Errores y Excepciones

Módulo 8: Temas Avanzados

Módulo 9: Pruebas y Depuración

Módulo 10: Desarrollo Web con Python

Módulo 11: Ciencia de Datos con Python

Módulo 12: Proyecto Final

© Copyright 2024. Todos los derechos reservados