使用 Docker 进行 C++ 集成测试:高级水平

面向初学者的在线Python训练器

轻松学习Python,无需理论负担。在浏览器中直接解决带自动检查的实践任务,无需安装任何东西。

开始课程

使用 Docker 进行 C++ 集成测试:高级水平

\n\n

集成测试是 C++ 开发中至关重要的一步,尤其是在现代微服务架构中。传统的在开发者环境中执行测试的方法,常常因环境差异、库版本和配置不同而导致错误。Docker 提供了一个优雅的解决方案:完全隔离、可重现性和自动化。在本文中,我们将探讨使用 Docker 对 C++ 应用程序进行集成测试的高级技术,包括依赖管理、并行测试执行以及与 CI/CD 的集成。

\n\n

1. 基于 Docker 的测试环境架构

\n\n

实现可靠集成测试的第一步是设计正确的 Docker 环境架构。我们不是创建一个单一的巨型容器,而是构建一个服务组合,每个服务负责其特定任务:被测服务本身、数据库、缓存、消息队列等。

\n\n

考虑一个使用 PostgreSQL 和 Redis 的 C++ 微服务示例。文件 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

关键点:

\n
    \n
  • 健康检查确保测试仅在依赖项就绪后启动。
  • \n
  • 独立网络(自动创建)将测试环境与生产环境隔离。
  • \n
  • 结果卷允许在测试完成后获取测试报告。
  • \n
\n\n

2. 编写适用于 Docker 的 C++ 集成测试

\n\n

您的测试应准备好运行在容器化环境中。这意味着连接到外部服务的配置应通过环境变量设置,而不是硬编码。

\n\n

使用 Google Test 和 libpqxx 连接 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                

博客

书籍推荐