Integration Testing C++ with Docker: From A to Z

Online Python Trainer for Beginners

Learn Python easily without overwhelming theory. Solve practical tasks with automatic checking, get hints in Russian, and write code directly in your browser — no installation required.

Start Course

Integration Testing C++ with Docker: From A to Z

\n\n

Integration testing is a key stage in the development of any serious C++ project. It allows you to verify how individual modules of the system work together, interact with databases, network services, and file systems. Docker in this context becomes an indispensable tool: it provides an isolated, reproducible environment, eliminating the "it works on my machine" problem. In this article, we will cover the full cycle of setting up integration testing for C++ with Docker — from basic concepts to advanced practices.

\n\n

1. Why Docker for C++ Integration Testing?

\n\n

Traditional C++ integration tests often suffer from environment issues: different library versions, incompatible compilers, specific OS settings. Docker solves these problems once and for all. Key advantages:

\n\n
    \n
  • Reproducibility: each test runs in an identical environment, regardless of the host system.
  • \n
  • Isolation: containers do not affect each other or the host system.
  • \n
  • Scalability: easily run hundreds of tests in parallel.
  • \n
  • CI/CD Integration: containers fit perfectly into Jenkins, GitLab CI, GitHub Actions pipelines.
  • \n
\n\n

Consider a simple example: your C++ application uses PostgreSQL. Without Docker, you would have to install and configure PostgreSQL on each test server. With Docker, it is one line of configuration.

\n\n

2. Setting Up Docker Environment for a C++ Project

\n\n

Let's start by creating a Dockerfile for our C++ application. Assume the project uses CMake and Google Test for unit tests, but we need integration tests with a real database.

\n\n

Basic Dockerfile for building and testing:

\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# Stage for tests\nFROM builder AS tester\nCMD ["./build/integration_tests"]
\n\n

Docker Compose for launching infrastructure:

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

3. Writing Integration Tests in C++

\n\n

Consider an example of an integration test that checks interaction with PostgreSQL via the libpqxx library. Assume we have a module for working with users.

\n\n

Example integration test:

\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        // Create test table\n        pqxx::work txn(*conn);\n        txn.exec("CREATE TABLE IF NOT EXISTS use                

Blogs

Book Recommendations