¿Por qué "solo las pruebas unitarias" ya no son suficientes?
\n\nEscribiste código C++ perfecto. La compilación fue exitosa, las pruebas unitarias están en verde, la revisión de código fue aprobada. Publicas la versión — y una hora después los usuarios se quejan: "el botón no funciona", "la base de datos no responde", "la GUI se congela". ¿Te suena familiar?
\n\nEl problema es que las pruebas unitarias verifican una función, pero no verifican un escenario. Están aisladas. Pero en el mundo real, tu código C++ interactúa con la red, el sistema de archivos, la GPU, APIs externas y otros hilos. Aquí es donde entran en juego las pruebas E2E de aplicaciones C++ (End-to-End o pruebas de extremo a extremo).
\n\nEn este artículo, veremos cómo convertir el caos de los errores de integración en un sistema ordenado de verificaciones automáticas. Aprenderás qué herramientas realmente funcionan, cómo escribir pruebas que no fallen en el primer intento y cómo integrar E2E en un pipeline de CI/CD. ¡Vamos allá!
\n\n¿Qué son las pruebas E2E en el contexto de C++?
\n\nLas pruebas E2E son la verificación de un escenario de usuario completo "de principio a fin". A diferencia de las pruebas unitarias, que verifican una función individual, una prueba E2E ejecuta tu aplicación (o su parte críticamente importante) en un entorno lo más parecido posible a producción.
\n\nPara C++, esto puede significar:
\n- \n
- Aplicación de escritorio: abrir una ventana, hacer clic en el botón "Enviar", verificar que los datos se enviaron a la BD. \n
- Aplicación de servidor: enviar una solicitud HTTP a tu API REST, verificar la respuesta y el estado de la base de datos. \n
- Software embebido: aplicar una señal de entrada, verificar la señal de salida después de un tiempo determinado. \n
La diferencia clave es el entorno real. Nada de objetos mock para la base de datos o la red. Solo hardware real (o Docker).
\n\nHerramientas: ¿qué funciona realmente para C++ en 2024?
\n\nVamos al grano. Este es el stack que usamos en producción:
\n\n- \n
- Catch2 o Google Test — para escribir la estructura de las pruebas (Arrange-Act-Assert). \n
- Docker — para levantar entornos limpios (BD, colas, dependencias). \n
- Pytest + subprocess — para la orquestación (sí, Python, pero es ideal para unir binarios de C++). \n
- Selenium/Appium — si tienes una GUI en Qt o WebView. \n
- CMake + CTest — para ejecutar pruebas y recopilar resultados. \n
No intentes escribir pruebas E2E solo en C++. Es doloroso. Usa Python como pegamento — es más rápido para escenarios de integración.
\n\nPráctica: escribimos una prueba E2E para una API REST en C++
\n\nSupongamos que tenemos un servidor C++ con cpp-httplib (o crow, o drogon). Acepta solicitudes POST en /api/user y guarda el usuario en PostgreSQL.
Escribamos una prueba E2E que:
\n- \n
- Levante un contenedor Docker con PostgreSQL. \n
- Compile e inicie nuestro servidor. \n
- Envíe una solicitud HTTP mediante curl (o un cliente C++). \n
- Verifique que el usuario apareció en la BD. \n
Paso 1: Docker-compose para el entorno de prueba
\n\nversion: '3.8'\nservices:\n db:\n image: postgres:15\n environment:\n POSTGRES_DB: testdb\n POSTGRES_USER: testuser\n POSTGRES_PASSWORD: testpass\n ports:\n - "5432:5432"\n app:\n build: .\n depends_on:\n - db\n ports:\n - "8080:8080"\n environment:\n DB_HOST: db\n\n\nPaso 2: Prueba en C++ con Catch2
\n\n// test_e2e_api.cpp\n#include <catch2/catch_test_macros.hpp>\n#include <httplib.h>\n#include <nlohmann/json.hpp>\n#include <cstdlib>\n\nTEST_CASE("E2E: Create user via API and verify in DB") {\n // Arrange\n httplib::Client cli("localhost", 8080);\n nlohmann::json user = {\n {"name", "John Doe"}