Testes de Integração C++ com Docker
O desenvolvimento moderno em C++ exige não apenas escrever código de qualidade, mas também garantir seu funcionamento confiável em condições reais. O teste de integração é uma etapa chave que permite verificar a interação dos componentes do sistema: banco de dados, serviços de rede, sistema de arquivos. O uso do Docker para esses fins fornece um ambiente isolado e reproduzível, ideal para pipelines de CI/CD. Neste artigo, vamos abordar como configurar testes de integração de aplicações C++ com Docker e fornecer exemplos práticos.
Por que Docker para testes de integração C++?
As abordagens tradicionais para testes de integração C++ frequentemente enfrentam problemas:
- Dependência de ambiente: os testes podem funcionar na máquina do desenvolvedor, mas falhar no servidor de build devido a diferentes versões de bibliotecas.
- Complexidade de configuração: para testar com um banco de dados real ou API externa, é necessária configuração manual.
- Execução paralela: várias execuções de teste podem entrar em conflito devido a recursos compartilhados.
O Docker resolve esses problemas fornecendo contêineres leves e isolados. Você pode levantar um banco de dados de teste, iniciar seu serviço C++ e executar os testes — tudo dentro de um único arquivo docker-compose. Isso garante que o ambiente será idêntico em qualquer máquina.
Configuração do projeto: exemplo básico
Vamos considerar um serviço C++ simples que salva dados no PostgreSQL. Para o teste de integração, precisaremos de:
- O próprio código C++ com os testes (usando Google Test).
- Um
Dockerfilepara compilar e executar os testes. - Um arquivo
docker-compose.ymlpara orquestrar os contêineres.
Estrutura do projeto:
my_cpp_project/├── src/│ ├── main.cpp│ ├── database.cpp│ └── database.h├── tests/│ └── test_integration.cpp├── CMakeLists.txt├── Dockerfile└── docker-compose.yml
Dockerfile:
FROM gcc:latest AS builder
WORKDIR /appCOPY . .
RUN apt-get update && apt-get install -y cmake libpq-devRUN cmake -B build -DCMAKE_BUILD_TYPE=ReleaseRUN cmake --build build
FROM ubuntu:22.04
RUN apt-get update && apt-get install -y libpq-devCOPY --from=builder /app/build/tests /app/testsCOPY --from=builder /app/build/my_app /app/my_app
ENTRYPOINT ["/app/tests"]docker-compose.yml:
version: '3.8'services: db: image: postgres:15 environment: POSTGRES_USER: testuser POSTGRES_PASSWORD: testpass POSTGRES_DB: testdb ports: - "5432:5432" healthcheck: test: ["CMD-SHELL", "pg_isready -U testuser -d testdb"] interval: 5s timeout: 5s retries: 5
test: build: . depends_on: db: condition: service_healthy environment: DB_HOST: db DB_PORT: 5432 DB_USER: testuser DB_PASSWORD: testpass DB_NAME: testdbEscrevendo testes de integração em C++
Agora vamos criar um teste que verifica a escrita e leitura do banco de dados. Usaremos Google Test e a biblioteca libpqxx para trabalhar com PostgreSQL.
tests/test_integration.cpp:
#include <gtest/gtest.h>#include <pqxx/pqxx>#include <string>
class DatabaseTest : public ::testing::Test {protected: void SetUp() override { conn = new pqxx::connection( "host=" + std::string(std::getenv("DB_HOST")) + " port=" + std::string(std::getenv("DB_PORT")) + " user=" + std::string(std::getenv("DB_USER")) + " password=" + std::string(std::getenv("DB_PASSWORD")) + " dbname=" + std::string(std::getenv("DB_NAME"))); }
void TearDown() override { delete conn; }
pqxx::connection* conn;};
TEST_F(DatabaseTest, InsertAndSelect) { pqxx::work txn(*conn); txn.exec("CREATE TABLE IF NOT EXISTS test_table (id SERIAL PRIMARY KEY, value TEXT);"); txn.exec("INSERT INTO test_table (value) VALUES ('hello');"); pqxx::result result = txn.exec("SELECT value FROM test_table;"); EXPECT_EQ(result[0][0].as<std::string>(), "hello"); txn.commit();}Com esta configuração, você pode executar docker-compose up --build e os testes serão executados automaticamente no contêiner, conectando-se ao banco de dados PostgreSQL. O ambiente é completamente isolado e reproduzível, tornando esta abordagem ideal para pipelines de CI/CD.