Tests d'intégration C++ avec Docker : niveau avancé

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

Tests d'intégration C++ avec Docker : niveau avancé

\n\n

Les 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\n

1. Architecture de l'environnement de test avec Docker

\n\n

La 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\n

Prenons l'exemple d'un microservice C++ qui utilise PostgreSQL et Redis. Fichier 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

Points 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
\n\n

2. Rédaction de tests d'intégration en C++ adaptés à Docker

\n\n

Vos 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\n

Exemple 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                

Blogs

Book Recommendations