Pruebas de Integración de C++ con Docker: De la A a la Z
\n\nLas pruebas de integración son una etapa clave en el desarrollo de cualquier proyecto serio de C++. Permiten verificar cómo los módulos individuales del sistema funcionan juntos, interactúan con bases de datos, servicios de red y sistemas de archivos. Docker en este contexto se convierte en una herramienta indispensable: proporciona un entorno aislado y reproducible, eliminando los problemas de "funciona en mi máquina". En este artículo, analizaremos el ciclo completo de configuración de pruebas de integración de C++ con Docker, desde conceptos básicos hasta prácticas avanzadas.
\n\n1. ¿Por qué Docker para pruebas de integración de C++?
\n\nLas pruebas de integración tradicionales de C++ a menudo sufren de problemas de entorno: diferentes versiones de bibliotecas, compiladores incompatibles, configuraciones específicas del sistema operativo. Docker resuelve estos problemas de una vez por todas. Las principales ventajas son:
\n\n- \n
- Reproducibilidad: cada prueba se ejecuta en un entorno idéntico, independientemente del sistema anfitrión. \n
- Aislamiento: los contenedores no se afectan entre sí ni al sistema anfitrión. \n
- Escalabilidad: es fácil ejecutar cientos de pruebas en paralelo. \n
- Integración CI/CD: los contenedores encajan perfectamente en los pipelines de Jenkins, GitLab CI, GitHub Actions. \n
Consideremos un ejemplo simple: su aplicación C++ usa PostgreSQL. Sin Docker, tendría que instalar y configurar PostgreSQL en cada servidor de pruebas. Con Docker, esto es una línea de configuración.
\n\n2. Configuración del entorno Docker para un proyecto C++
\n\nEmpecemos creando un Dockerfile para nuestra aplicación C++. Supongamos que el proyecto usa CMake y Google Test para pruebas unitarias, pero necesitamos pruebas de integración con una base de datos real.
\n\nDockerfile básico para compilación y pruebas:
\n\n# Dockerfile\nFROM ubuntu:22.04 AS builder\n\nRUN apt-get update && apt-get install -y \\\n build-essential \\\n cmake \\\n git \\\n libpq-dev \\\n libgtest-dev \\\n && rm -rf /var/lib/apt/lists/*\n\nWORKDIR /app\nCOPY . .\n\nRUN cmake -B build -DCMAKE_BUILD_TYPE=Release \\\n && cmake --build build --parallel\n\n# Etapa para pruebas\nFROM builder AS tester\nCMD ["./build/integration_tests"]\n\nDocker Compose para iniciar la infraestructura:
\n\n# docker-compose.yml\nversion: '3.8'\n\nservices:\n db:\n image: postgres:15\n environment:\n POSTGRES_DB: testdb\n POSTGRES_USER: testuser\n POSTGRES_PASSWORD: testpass\n healthcheck:\n test: ["CMD-SHELL", "pg_isready -U testuser -d testdb"]\n interval: 5s\n timeout: 5s\n retries: 5\n\n app:\n build: .\n depends_on:\n db:\n condition: service_healthy\n environment:\n DB_HOST: db\n DB_PORT: 5432\n DB_NAME: testdb\n DB_USER: testuser\n DB_PASSWORD: testpass\n command: ["./build/integration_tests"]\n\n3. Escritura de pruebas de integración en C++
\n\nConsideremos un ejemplo de prueba de integración que verifica la interacción con PostgreSQL a través de la biblioteca libpqxx. Supongamos que tenemos un módulo para trabajar con usuarios.
\n\nEjemplo de prueba de integración:
\n\n// integration_tests.cpp\n#include <gtest/gtest.h>\n#include <pqxx/pqxx>\n#include <string>\n#include <vector>\n\nclass DatabaseIntegrationTest : public ::testing::Test {\nprotected:\n void SetUp() override {\n conn = new pqxx::connection(\n "host=" + std::getenv("DB_HOST") +\n " port=" + std::getenv("DB_PORT") +\n " dbname=" + std::getenv("DB_NAME") +\n " user=" + std::getenv("DB_USER") +\n " password=" + std::getenv("DB_PASSWORD")\n );\n \n // Creamos la tabla de prueba\n pqxx::work txn(*conn);\n txn.exec("CREATE TABLE IF NOT EXISTS use