En este módulo, aprenderás sobre las técnicas y herramientas esenciales para depurar y probar tu código en C++. La depuración y las pruebas son componentes críticos del desarrollo de software, ya que aseguran que tu código funcione correctamente y sea robusto frente a errores.
- Introducción a la Depuración
¿Qué es la Depuración?
La depuración es el proceso de identificar y corregir errores en el código. Estos errores pueden ser de varios tipos, como errores de sintaxis, errores lógicos o errores en tiempo de ejecución.
Herramientas de Depuración
Las herramientas de depuración te permiten ejecutar tu código paso a paso, inspeccionar variables y evaluar expresiones. Algunas herramientas populares incluyen:
- GDB (GNU Debugger): Un depurador de código abierto para C y C++.
- LLDB: Un depurador de código abierto que forma parte del proyecto LLVM.
- Depuradores integrados en IDEs: Como el depurador de Visual Studio, CLion, Code::Blocks, etc.
Ejemplo Práctico con GDB
A continuación, se muestra un ejemplo de cómo usar GDB para depurar un programa simple en C++.
#include <iostream> int main() { int a = 5; int b = 0; int c = a / b; // Esto causará un error de división por cero std::cout << "Resultado: " << c << std::endl; return 0; }
Para depurar este programa con GDB:
- Compila el programa con la opción
-g
para incluir información de depuración:g++ -g -o programa programa.cpp
- Inicia GDB con el ejecutable:
gdb ./programa
- Dentro de GDB, establece un punto de interrupción en la línea donde ocurre la división:
(gdb) break main
- Ejecuta el programa:
(gdb) run
- Usa comandos como
next
para avanzar línea por línea yprint
para inspeccionar variables:(gdb) next (gdb) print a (gdb) print b
- Técnicas de Depuración
Puntos de Interrupción (Breakpoints)
Los puntos de interrupción te permiten pausar la ejecución del programa en una línea específica de código. Esto es útil para inspeccionar el estado del programa en momentos críticos.
Inspección de Variables
Durante la depuración, puedes inspeccionar el valor de las variables para verificar si contienen los valores esperados.
Seguimiento de la Pila de Llamadas (Call Stack)
El seguimiento de la pila de llamadas te permite ver la secuencia de llamadas de funciones que llevaron al punto actual de ejecución. Esto es útil para entender el flujo del programa y localizar el origen de los errores.
- Introducción a las Pruebas
¿Qué son las Pruebas?
Las pruebas son el proceso de ejecutar tu código con diferentes entradas para verificar que produce los resultados esperados. Las pruebas pueden ser manuales o automatizadas.
Tipos de Pruebas
- Pruebas Unitarias: Verifican el funcionamiento de unidades individuales de código, como funciones o clases.
- Pruebas de Integración: Verifican que diferentes unidades de código funcionen correctamente juntas.
- Pruebas de Sistema: Verifican el sistema completo para asegurar que cumple con los requisitos.
Herramientas de Pruebas
- Google Test: Un marco de pruebas unitarias para C++.
- Catch2: Otro marco de pruebas unitarias para C++.
Ejemplo Práctico con Google Test
A continuación, se muestra un ejemplo de cómo escribir una prueba unitaria usando Google Test.
-
Instala Google Test siguiendo las instrucciones en su repositorio de GitHub.
-
Escribe una función simple y su prueba unitaria:
// archivo: funciones.cpp int suma(int a, int b) { return a + b; } // archivo: funciones_test.cpp #include <gtest/gtest.h> #include "funciones.cpp" TEST(SumaTest, SumaPositivos) { EXPECT_EQ(suma(1, 2), 3); } TEST(SumaTest, SumaNegativos) { EXPECT_EQ(suma(-1, -2), -3); } int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }
- Compila y ejecuta las pruebas:
g++ -std=c++11 -isystem /path/to/googletest/include -pthread funciones_test.cpp /path/to/googletest/libgtest.a /path/to/googletest/libgtest_main.a -o funciones_test ./funciones_test
- Ejercicios Prácticos
Ejercicio 1: Depuración con GDB
- Escribe un programa en C++ que contenga un error lógico.
- Usa GDB para identificar y corregir el error.
Ejercicio 2: Pruebas Unitarias con Google Test
- Escribe una función que calcule el factorial de un número.
- Escribe pruebas unitarias para verificar que la función funciona correctamente para varios casos (números positivos, cero, etc.).
Soluciones
Ejercicio 1: Depuración con GDB
#include <iostream> int main() { int x = 10; int y = 0; int z = x / y; // Error: división por cero std::cout << "Resultado: " << z << std::endl; return 0; }
Para depurar:
- Compila con
-g
:g++ -g -o programa programa.cpp
- Inicia GDB:
gdb ./programa
- Establece un punto de interrupción:
(gdb) break main
- Ejecuta:
(gdb) run
- Inspecciona variables y corrige el error.
Ejercicio 2: Pruebas Unitarias con Google Test
// archivo: factorial.cpp int factorial(int n) { if (n == 0) return 1; return n * factorial(n - 1); } // archivo: factorial_test.cpp #include <gtest/gtest.h> #include "factorial.cpp" TEST(FactorialTest, Positivos) { EXPECT_EQ(factorial(5), 120); EXPECT_EQ(factorial(3), 6); } TEST(FactorialTest, Cero) { EXPECT_EQ(factorial(0), 1); } int main(int argc, char **argv) { ::testing::InitGoogleTest(&argc, argv); return RUN_ALL_TESTS(); }
Compila y ejecuta las pruebas como se indicó anteriormente.
Conclusión
En esta sección, has aprendido sobre las técnicas y herramientas esenciales para depurar y probar tu código en C++. La depuración te ayuda a identificar y corregir errores, mientras que las pruebas aseguran que tu código funcione correctamente. Con estas habilidades, estarás mejor preparado para desarrollar software robusto y confiable.
Curso de Programación en C++
Módulo 1: Introducción a C++
- Introducción a C++
- Configuración del Entorno de Desarrollo
- Sintaxis y Estructura Básica
- Variables y Tipos de Datos
- Entrada y Salida
Módulo 2: Estructuras de Control
Módulo 3: Funciones
- Introducción a las Funciones
- Parámetros de Función y Tipos de Retorno
- Sobrecarga de Funciones
- Recursión
Módulo 4: Arreglos y Cadenas
- Introducción a los Arreglos
- Arreglos Multidimensionales
- Introducción a las Cadenas
- Manipulación de Cadenas
Módulo 5: Punteros y Referencias
- Introducción a los Punteros
- Aritmética de Punteros
- Punteros y Arreglos
- Referencias
- Asignación Dinámica de Memoria
Módulo 6: Programación Orientada a Objetos
- Introducción a la POO
- Clases y Objetos
- Constructores y Destructores
- Herencia
- Polimorfismo
- Encapsulación y Abstracción
Módulo 7: Temas Avanzados
- Plantillas
- Manejo de Excepciones
- Entrada/Salida de Archivos
- Biblioteca Estándar de Plantillas (STL)
- Expresiones Lambda
- Multihilo