Tests d'intégration C++ avec Docker : niveau avancé
\n\nLes tests d'intégration sont une étape cruciale du développement en C++, en particulier dans les architectures modernes de microservices. Les approches traditionnelles, où les tests sont exécutés dans l'environnement du développeur, conduisent souvent à des erreurs en raison des différences d'environnement, de versions de bibliothèques et de configurations. Docker offre une solution élégante : isolation complète, reproductibilité et automatisation. Dans cet article, nous explorerons les techniques avancées de tests d'intégration d'applications C++ avec Docker, y compris la gestion des dépendances, l'exécution parallèle des tests et l'intégration avec CI/CD.
\n\n1. Architecture de l'environnement de test avec Docker
\n\nLa première étape vers des tests d'intégration fiables est une architecture correcte de l'environnement Docker. Au lieu d'un seul conteneur monolithique, nous créons une composition de services, chacun responsable de sa propre tâche : le service testé lui-même, la base de données, le cache, les files de messages, etc.
\n\nPrenons l'exemple d'un microservice C++ qui utilise PostgreSQL et Redis. Fichier docker-compose.test.yml :
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\nPoints clés :
\n- \n
- Les healthchecks garantissent que les tests ne démarrent qu'après que les dépendances soient prêtes. \n
- Un réseau séparé (créé automatiquement) isole l'environnement de test de la production. \n
- Un volume pour les résultats permet de récupérer les rapports de test après la fin. \n
2. Rédaction de tests d'intégration en C++ adaptés à Docker
\n\nVos tests doivent être prêts à fonctionner dans un environnement conteneurisé. Cela signifie que la configuration de connexion aux services externes doit être définie via des variables d'environnement, et non codée en dur.
\n\nExemple de test utilisant Google Test et libpqxx pour 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