Pruebas de integración de C++ con Docker: nivel avanzado

Entrenador de Python en Línea para Principiantes

Aprende Python fácilmente sin sobrecargarte de teoría. Resuelve tareas prácticas con verificación automática, recibe pistas y escribe código directamente en el navegador, sin instalar nada.

Start Course

Pruebas de integración de C++ con Docker: nivel avanzado

\n\n

Las pruebas de integración son una etapa críticamente importante en el desarrollo de C++, especialmente en las arquitecturas modernas de microservicios. Los enfoques tradicionales, donde las pruebas se ejecutan en el entorno del desarrollador, a menudo conducen a errores debido a diferencias en el entorno, versiones de bibliotecas y configuraciones. Docker ofrece una solución elegante: aislamiento completo, reproducibilidad y automatización. En este artículo, exploraremos técnicas avanzadas de pruebas de integración para aplicaciones C++ utilizando Docker, incluyendo la gestión de dependencias, la ejecución paralela de pruebas y la integración con CI/CD.

\n\n

1. Arquitectura del entorno de pruebas con Docker

\n\n

El primer paso hacia pruebas de integración confiables es una arquitectura adecuada del entorno Docker. En lugar de un solo contenedor monolítico, creamos una composición de servicios, cada uno responsable de su propia tarea: el propio servicio bajo prueba, la base de datos, la caché, las colas de mensajes, etc.

\n\n

Consideremos un ejemplo para un microservicio C++ que utiliza PostgreSQL y Redis. Archivo docker-compose.test.yml:

\n\n
version: '3.8'\n\nservices:\n  postgres_test:\n    image: postgres:15-alpine\n    environment:\n      POSTGRES_USER: test_user\n      POSTGRES_PASSWORD: test_pass\n      POSTGRES_DB: test_db\n    healthcheck:\n      test: ["CMD-SHELL", "pg_isready -U test_user -d test_db"]\n      interval: 2s\n      timeout: 5s\n      retries: 10\n\n  redis_test:\n    image: redis:7-alpine\n    healthcheck:\n      test: ["CMD", "redis-cli", "ping"]\n      interval: 2s\n      timeout: 5s\n      retries: 10\n\n  cpp_service_test:\n    build:\n      context: .\n      dockerfile: Dockerfile.test\n    depends_on:\n      postgres_test:\n        condition: service_healthy\n      redis_test:\n        condition: service_healthy\n    environment:\n      - DB_HOST=postgres_test\n      - DB_PORT=5432\n      - REDIS_HOST=redis_test\n      - REDIS_PORT=6379\n      - TEST_MODE=1\n    volumes:\n      - ./test_results:/app/test_results\n    command: ["./run_integration_tests"]
\n\n

Puntos clave:

\n
    \n
  • Healthchecks garantizan que las pruebas se ejecuten solo después de que las dependencias estén listas.
  • \n
  • Red separada (creada automáticamente) aísla el entorno de prueba del de producción.
  • \n
  • Volumen para resultados permite recuperar los informes de prueba después de la finalización.
  • \n
\n\n

2. Escritura de pruebas de integración en C++ teniendo en cuenta Docker

\n\n

Sus pruebas deben estar preparadas para funcionar en un entorno contenerizado. Esto significa que la configuración de conexión a los servicios externos debe definirse a través de variables de entorno, no codificarse de forma fija.

\n\n

Ejemplo de prueba usando Google Test y libpqxx para PostgreSQL:

\n\n
#include <gtest/gtest.h>\n#include <pqxx/pqxx>\n#include <cstdlib>\n\nclass DatabaseIntegrationTest : public ::testing::Test {\nprotected:\n    std::unique_ptr<pqxx::connection> conn;\n\n    void SetUp() override {\n        const char* db_host = std::getenv("DB_HOST");\n        const char* db_port = std::getenv("DB_PORT");\n        const char* db_user = std::getenv("POSTGRES_USER");\n        const char* db_pass = std::getenv("POSTGRES_PASSWORD");\n        const char* db_name = std::getenv("POSTGRES_DB");\n\n        ASSERT_NE(db_host, nullptr) << "DB_HOST not set";\n        ASSERT_NE(db_port, nullptr) << "DB_PORT not set";\n\n        std::string conn_str = "host=" + std::string(db_host) +\n                               " port=" + std::string(db_port) +\n                               " user=" + std::string(db_user ? db_user : "test_user") +\n                               " password=" + std::string(db_pass ? db_pass : "test_pass") +\n                               " dbname=" + std::string(db_name ? db_name : "test_db");\n\n        try {\n            conn = std::make_unique<pqxx::connect                

Blogs

Book Recommendations