Cargando...

Pruebas unitarias

Las pruebas unitarias en C++ son una técnica fundamental para garantizar que cada componente individual del software, como funciones o clases, se comporte de manera correcta e independiente. Su importancia radica en la capacidad de detectar errores en etapas tempranas del desarrollo, mejorar la mantenibilidad del código y asegurar la calidad global de las aplicaciones.
En el desarrollo de C++, las pruebas unitarias deben aplicarse desde el diseño inicial de funciones y clases, especialmente cuando se realizan refactorizaciones o se añaden nuevas funcionalidades. Estas pruebas integran conceptos esenciales de C++ como la sintaxis, estructuras de datos, algoritmos eficientes y principios de programación orientada a objetos (OOP). Además, permiten validar correctamente excepciones y gestionar recursos de memoria de manera segura.
A través de este tutorial, el lector aprenderá a crear pruebas unitarias básicas y avanzadas, cómo manejar excepciones dentro de los tests, evitar fugas de memoria, y aplicar patrones de diseño seguros y optimizados. También se explorará cómo estas pruebas encajan en un ciclo de desarrollo más amplio, incluyendo la integración con frameworks de prueba como Google Test o Catch2, así como la implementación de enfoques TDD (Test-Driven Development) en proyectos reales.

Ejemplo Básico

text
TEXT Code
\#include <iostream>
\#include <vector>
\#include <cassert>

int sumaVector(const std::vector<int>& numeros) {
int suma = 0;
for (int num : numeros) {
suma += num;
}
return suma;
}

void testSumaVector() {
std::vector<int> test1 {1, 2, 3, 4, 5};
assert(sumaVector(test1) == 15);

std::vector<int> test2 {-1, -2, -3};
assert(sumaVector(test2) == -6);

std::vector<int> test3 {};
assert(sumaVector(test3) == 0);

std::cout << "Todos los tests básicos pasaron correctamente!" << std::endl;

}

int main() {
testSumaVector();
return 0;
}

En este ejemplo, la función sumaVector calcula la suma de los elementos de un vector. La función de prueba testSumaVector evalúa escenarios con números positivos, negativos y un vector vacío. El uso de assert garantiza que si un test falla, el programa se detenga y notifique el error.
El paso de parámetros por referencia constante (const std::vector<int>&) evita copias innecesarias, mejorando el rendimiento. La iteración con rango (range-based for) hace que el código sea más legible y claro. Este patrón permite probar funciones de manera modular y aumenta la mantenibilidad del código, facilitando la integración de tests en proyectos C++ más grandes.

Ejemplo Práctico

text
TEXT Code
\#include <iostream>
\#include <stdexcept>
\#include <cassert>

class CuentaBancaria {
private:
std::string titular;
double saldo;

public:
CuentaBancaria(const std::string& nombre, double saldoInicial) : titular(nombre), saldo(saldoInicial) {
if (saldoInicial < 0) throw std::invalid_argument("El saldo inicial no puede ser negativo");
}

void depositar(double cantidad) {
if (cantidad <= 0) throw std::invalid_argument("La cantidad a depositar debe ser positiva");
saldo += cantidad;
}

void retirar(double cantidad) {
if (cantidad > saldo) throw std::runtime_error("Saldo insuficiente");
saldo -= cantidad;
}

double obtenerSaldo() const { return saldo; }

};

void testCuentaBancaria() {
CuentaBancaria cuenta("Carlos", 100.0);

cuenta.depositar(50.0);
assert(cuenta.obtenerSaldo() == 150.0);

cuenta.retirar(30.0);
assert(cuenta.obtenerSaldo() == 120.0);

try {
cuenta.retirar(200.0);
assert(false);
} catch (const std::runtime_error&) {
assert(true);
}

try {
CuentaBancaria cuentaInvalida("Ana", -10.0);
assert(false);
} catch (const std::invalid_argument&) {
assert(true);
}

std::cout << "Todos los tests avanzados pasaron correctamente!" << std::endl;

}

int main() {
testCuentaBancaria();
return 0;
}

Este ejemplo muestra la clase CuentaBancaria y cómo probar sus operaciones y manejo de excepciones. Los bloques try-catch permiten verificar que el programa reaccione correctamente ante errores. La combinación de referencias constantes, manejo de excepciones y assert asegura robustez y seguridad del código. Este enfoque es aplicable en proyectos complejos donde se requiere validar la lógica de negocio y garantizar que los módulos funcionen de manera independiente y confiable.

Mejores prácticas y errores comunes en pruebas unitarias en C++:

  • Usar referencias constantes para evitar copias innecesarias.
  • Mantener los tests independientes y deterministas.
  • Verificar valores límite y excepciones.
  • Usar smart pointers para evitar fugas de memoria.
  • Seguir estándares de nomenclatura y estilo de codificación.
    Errores comunes:

  • Usar punteros sin gestionar memoria (raw pointers).

  • Dependencia entre tests.
  • Algoritmos ineficientes para grandes volúmenes de datos.
  • Ignorar manejo de excepciones.
  • Combinar código de prueba y producción en el mismo bloque.

📊 Tabla de Referencia

C++ Element/Concept Description Usage Example
Función sumaVector Calcula la suma de los elementos de un vector int resultado = sumaVector({1,2,3});
Macro assert Valida condiciones y detiene ejecución si falla assert(resultado == 6);
Clase CuentaBancaria Gestión de operaciones bancarias CuentaBancaria cuenta("Carlos", 100.0);
Bloque try-catch Verificación y manejo de excepciones try { cuenta.retirar(200); } catch(...) {}
Referencia constante const Previene copias y protege datos void depositar(const double& cantidad);

Las pruebas unitarias en C++ aumentan la confiabilidad y previsibilidad del código, permiten detectar errores rápidamente y facilitan la implementación de TDD. Tras este tutorial, se recomienda explorar frameworks como Google Test y Catch2, integrar pruebas en el proceso de compilación y validar módulos dentro de sistemas más grandes para asegurar el correcto funcionamiento independiente y combinado de los componentes.

🧠 Pon a Prueba tu Conocimiento

Listo para Empezar

Pon a Prueba tu Conocimiento

Ponte a prueba con este cuestionario interactivo y descubre qué tan bien entiendes el tema

4
Preguntas
🎯
70%
Para Aprobar
♾️
Tiempo
🔄
Intentos

📝 Instrucciones

  • Lee cada pregunta cuidadosamente
  • Selecciona la mejor respuesta para cada pregunta
  • Puedes repetir el quiz tantas veces como quieras
  • Tu progreso se mostrará en la parte superior