Testes de Integração JavaScript com Docker: da Teoria à Prática Avançada
\n\nTestes de integração são uma etapa crítica no desenvolvimento, que verifica a interação entre diferentes módulos e serviços externos. Para aplicações JavaScript em Node.js, o Docker se torna uma ferramenta indispensável, permitindo criar ambientes isolados e reproduzíveis para testes. Neste artigo, exploraremos técnicas avançadas de configuração de testes de integração com Docker, incluindo trabalho com bancos de dados, filas e otimização para CI/CD.
\n\nPor que Docker para Testes de Integração?
\n\nAbordagens tradicionais para testes de integração (mocks, stubs) nem sempre refletem o comportamento real do sistema. O Docker resolve esse problema, fornecendo:
\n\n- \n
- Isolamento: cada teste é executado em um contêiner limpo, sem influenciar outros testes ou o ambiente local. \n
- Reprodutibilidade: condições de execução idênticas na máquina do desenvolvedor e no CI/CD. \n
- Escalabilidade: possibilidade de executar testes em paralelo com diferentes versões de dependências (PostgreSQL, Redis, Elasticsearch). \n
- Recuperação rápida: recriação de contêineres leva segundos, não horas de configuração. \n
Configuração de um Ambiente de Teste Avançado
\n\nVamos considerar uma aplicação Node.js típica que usa PostgreSQL e Redis. Em vez de um simples docker-compose.yml, criaremos uma configuração flexível com suporte para testes paralelos e health checks.
Passo 1: Docker Compose com Portas Dinâmicas
\n\nPara evitar conflitos de porta durante a execução paralela, usamos alocação dinâmica:
\n\n# docker-compose.test.yml\nversion: '3.8'\nservices:\n postgres_test:\n image: postgres:15-alpine\n environment:\n POSTGRES_DB: test_db\n POSTGRES_USER: test_user\n POSTGRES_PASSWORD: test_pass\n ports:\n - "0:5432" # Porta dinâmica\n healthcheck:\n test: ["CMD-SHELL", "pg_isready -U test_user -d test_db"]\n interval: 2s\n timeout: 5s\n retries: 10\n tmpfs: /var/lib/postgresql/data # Dados na RAM para velocidade\n\n redis_test:\n image: redis:7-alpine\n ports:\n - "0:6379"\n healthcheck:\n test: ["CMD", "redis-cli", "ping"]\n interval: 2s\n timeout: 5s\n retries: 10\n\nPasso 2: Utilitários para Executar Testes com Docker
\n\nCriaremos uma classe auxiliar que encontra automaticamente as portas dinâmicas e aguarda a prontidão dos serviços:
\n\n// test/setup/docker-manager.js\nconst { DockerComposeEnvironment, Wait } = require('testcontainers');\nconst { Client } = require('pg');\nconst Redis = require('ioredis');\n\nclass DockerTestManager {\n constructor() {\n this.environment = null;\n this.config = {\n pgPort: null,\n redisPort: null\n };\n }\n\n async start() {\n this.environment = await new DockerComposeEnvironment(\n '.', \n 'docker-compose.test.yml'\n ).withWaitStrategy('postgres_test', Wait.forHealthCheck())\n .withWaitStrategy('redis_test', Wait.forHealthCheck())\n .up();\n\n // Extrai o mapeamento de portas\n const pgContainer = this.environment.getContainer('postgres_test');\n const redisContainer = this.environment.getContainer('redis_test');\n \n this.config.pgPort = pgContainer.getMappedPort(5432);\n this.config.redisPort = redisContainer.getMappedPort(6379);\n \n return this.config;\n }\n\n async stop() {\n if (this.environment) {\n await this.environment.down();\n }\n }\n}\n\nmodule.exports = DockerTestManager;\n\nCenários Avançados de Teste de Integração
\n\nAgora, vamos para testes específicos que verificam a interação real dos componentes.
\n