Teste de Integração C++ com Docker: do Básico ao Avançado
\n\nO teste de integração é uma etapa fundamental no desenvolvimento de qualquer projeto C++ sério. Ele permite verificar como os módulos individuais do sistema funcionam juntos, interagem com bancos de dados, serviços de rede e sistemas de arquivos. O Docker, nesse contexto, torna-se uma ferramenta indispensável: ele fornece um ambiente isolado e reproduzível, eliminando problemas do tipo "funciona na minha máquina". Neste artigo, abordaremos o ciclo completo de configuração de testes de integração C++ com Docker — desde conceitos básicos até práticas avançadas.
\n\n1. Por que Docker para testes de integração C++?
\n\nOs testes de integração C++ tradicionais frequentemente sofrem com problemas de ambiente: versões diferentes de bibliotecas, compiladores incompatíveis, configurações específicas do sistema operacional. O Docker resolve esses problemas de uma vez por todas. Principais vantagens:
\n\n- \n
- Reprodutibilidade: cada teste é executado em um ambiente idêntico, independentemente do sistema host. \n
- Isolamento: os contêineres não afetam uns aos outros nem o sistema host. \n
- Escalabilidade: fácil executar centenas de testes em paralelo. \n
- Integração CI/CD: contêineres se encaixam perfeitamente em pipelines Jenkins, GitLab CI, GitHub Actions. \n
Vamos considerar um exemplo simples: sua aplicação C++ usa PostgreSQL. Sem Docker, você precisaria instalar e configurar o PostgreSQL em cada servidor de teste. Com Docker, isso é uma linha de configuração.
\n\n2. Configuração do ambiente Docker para projeto C++
\n\nComeçaremos criando um Dockerfile para nossa aplicação C++. Suponha que o projeto use CMake e Google Test para testes unitários, mas precisamos de testes de integração com um banco de dados real.
\n\nDockerfile básico para compilação e teste:
\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# Estágio para testes\nFROM builder AS tester\nCMD ["./build/integration_tests"]\n\nDocker Compose para iniciar a infraestrutura:
\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\n3. Escrevendo testes de integração em C++
\n\nVamos considerar um exemplo de teste de integração que verifica a interação com PostgreSQL através da biblioteca libpqxx. Suponha que temos um módulo para trabalhar com usuários.
\n\nExemplo de teste de integração:
\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 // Criando tabela de teste\n pqxx::work txn(*conn);\n txn.exec("CREATE TABLE IF NOT EXISTS use