En esta sección, aprenderemos sobre la importancia de las pruebas y la depuración en el desarrollo de software. Veremos diferentes técnicas y herramientas que nos ayudarán a identificar y corregir errores en nuestro código.

  1. Introducción a las Pruebas

Las pruebas son una parte esencial del desarrollo de software. Nos permiten verificar que nuestro código funciona como se espera y que no contiene errores. Existen varios tipos de pruebas, cada una con su propósito específico.

Tipos de Pruebas

  1. Pruebas Unitarias:

    • Verifican el funcionamiento de componentes individuales del código, como funciones o métodos.
    • Ejemplo: Probar una función que suma dos números para asegurarse de que devuelve el resultado correcto.
  2. Pruebas de Integración:

    • Verifican que diferentes componentes del sistema funcionen correctamente juntos.
    • Ejemplo: Probar que una función que depende de otra función se comporte correctamente cuando ambas se usan juntas.
  3. Pruebas de Sistema:

    • Verifican el sistema completo para asegurarse de que cumple con los requisitos especificados.
    • Ejemplo: Probar una aplicación completa para asegurarse de que todas las funcionalidades funcionan correctamente.
  4. Pruebas de Aceptación:

    • Verifican que el sistema cumple con los criterios de aceptación definidos por el cliente o usuario final.
    • Ejemplo: Probar que una aplicación cumple con todos los requisitos del cliente antes de su entrega.

Herramientas de Pruebas

  • Google Test: Un framework de pruebas unitarias para C++.
  • Catch2: Otro popular framework de pruebas unitarias para C++.
  • CTest: Una herramienta de pruebas que se integra con CMake.

  1. Introducción a la Depuración

La depuración es el proceso de identificar y corregir errores en el código. Es una habilidad crucial para cualquier programador, ya que los errores son inevitables en el desarrollo de software.

Técnicas de Depuración

  1. Impresión de Mensajes (Print Debugging):

    • Utilizar std::cout para imprimir mensajes y valores de variables en diferentes puntos del código.
    • Ejemplo:
      int main() {
          int a = 5;
          int b = 10;
          std::cout << "Valor de a: " << a << std::endl;
          std::cout << "Valor de b: " << b << std::endl;
          int c = a + b;
          std::cout << "Valor de c: " << c << std::endl;
          return 0;
      }
      
  2. Uso de Depuradores (Debuggers):

    • Herramientas que permiten ejecutar el código paso a paso, inspeccionar variables y modificar el flujo de ejecución.
    • Ejemplo: GDB (GNU Debugger) para C++.
  3. Puntos de Interrupción (Breakpoints):

    • Puntos en el código donde la ejecución se detiene para permitir la inspección del estado del programa.
    • Ejemplo: Establecer un punto de interrupción en una línea específica del código usando un depurador.

Herramientas de Depuración

  • GDB (GNU Debugger): Un depurador para programas escritos en C, C++ y otros lenguajes.
  • LLDB: El depurador del proyecto LLVM, compatible con C++.
  • Visual Studio Debugger: Un depurador integrado en el IDE de Visual Studio.

  1. Ejemplo Práctico de Pruebas y Depuración

Pruebas Unitarias con Google Test

  1. Instalación de Google Test:

  2. Escribir una Prueba Unitaria:

    • Crear un archivo de prueba, por ejemplo, test.cpp:
      #include <gtest/gtest.h>
      
      int Suma(int a, int b) {
          return a + b;
      }
      
      TEST(SumaTest, PositiveNumbers) {
          EXPECT_EQ(Suma(1, 2), 3);
          EXPECT_EQ(Suma(10, 20), 30);
      }
      
      TEST(SumaTest, NegativeNumbers) {
          EXPECT_EQ(Suma(-1, -2), -3);
          EXPECT_EQ(Suma(-10, -20), -30);
      }
      
      int main(int argc, char **argv) {
          ::testing::InitGoogleTest(&argc, argv);
          return RUN_ALL_TESTS();
      }
      
  3. Compilar y Ejecutar las Pruebas:

    • Compilar el archivo de prueba:
      g++ -std=c++11 -isystem /path/to/googletest/include -pthread test.cpp /path/to/googletest/lib/libgtest.a -o test
      
    • Ejecutar las pruebas:
      ./test
      

Depuración con GDB

  1. Compilar el Código con Información de Depuración:

    • Añadir la opción -g al compilar el código:
      g++ -g main.cpp -o main
      
  2. Iniciar GDB:

    • Ejecutar el programa dentro de GDB:
      gdb ./main
      
  3. Establecer Puntos de Interrupción y Ejecutar el Programa:

    • Establecer un punto de interrupción en la función main:
      (gdb) break main
      
    • Ejecutar el programa:
      (gdb) run
      
  4. Inspeccionar Variables y Continuar la Ejecución:

    • Inspeccionar el valor de una variable:
      (gdb) print a
      
    • Continuar la ejecución hasta el siguiente punto de interrupción:
      (gdb) continue
      

  1. Ejercicio Práctico

Ejercicio

  1. Escribe una función que calcule el factorial de un número entero.
  2. Escribe pruebas unitarias para verificar que la función de factorial funciona correctamente.
  3. Introduce un error intencional en la función de factorial y utiliza GDB para depurar y corregir el error.

Solución

  1. Función de Factorial:

    int Factorial(int n) {
        if (n <= 1) return 1;
        return n * Factorial(n - 1);
    }
    
  2. Pruebas Unitarias:

    #include <gtest/gtest.h>
    
    int Factorial(int n);
    
    TEST(FactorialTest, PositiveNumbers) {
        EXPECT_EQ(Factorial(1), 1);
        EXPECT_EQ(Factorial(2), 2);
        EXPECT_EQ(Factorial(3), 6);
        EXPECT_EQ(Factorial(4), 24);
    }
    
    TEST(FactorialTest, Zero) {
        EXPECT_EQ(Factorial(0), 1);
    }
    
    int main(int argc, char **argv) {
        ::testing::InitGoogleTest(&argc, argv);
        return RUN_ALL_TESTS();
    }
    
  3. Introducir un Error y Depurar:

    • Introducir un error en la función de factorial:
      int Factorial(int n) {
          if (n <= 1) return 1;
          return n * Factorial(n - 2); // Error intencional
      }
      
    • Compilar con información de depuración y usar GDB para identificar y corregir el error.

Conclusión

En esta sección, hemos aprendido sobre la importancia de las pruebas y la depuración en el desarrollo de software. Hemos visto diferentes tipos de pruebas y técnicas de depuración, así como herramientas útiles para cada tarea. Además, hemos practicado con ejemplos prácticos para reforzar los conceptos aprendidos. Con estas habilidades, estarás mejor preparado para escribir código robusto y libre de errores.

© Copyright 2024. Todos los derechos reservados