Teste de Integração TypeScript com Docker: Nível Avançado
O teste de integração é uma etapa crucial no desenvolvimento de aplicações TypeScript modernas. Quando seu sistema consiste em vários microsserviços, bancos de dados, filas de mensagens e APIs externas, os testes unitários isolados deixam de cobrir cenários reais de interação. O Docker permite criar ambientes reproduzíveis e isolados para testes, próximos ao ambiente de produção. Neste artigo, abordaremos técnicas avançadas de teste de integração de aplicações TypeScript usando Docker: desde a configuração de contêineres até a construção de pipelines CI/CD.
Por que o Docker é a ferramenta ideal para testes de integração TypeScript
As abordagens tradicionais para teste de integração frequentemente sofrem com problemas de ambiente: "funciona na minha máquina". O Docker resolve esse problema fornecendo:
- Isolamento — cada teste é executado em um contêiner limpo, sem influenciar outros processos
- Reprodutibilidade — mesmo ambiente em todas as etapas: local, CI, staging
- Velocidade — contêineres leves são iniciados em segundos
- Flexibilidade — fácil combinar diferentes versões de bancos de dados, caches, filas
Para projetos TypeScript, o Docker é especialmente útil, pois permite testar não apenas o runtime Node.js, mas também a interação com o compilador TypeScript, transpilação e construção.
Configuração do ambiente Docker para testes TypeScript
Vamos começar com a configuração básica. Criaremos um Dockerfile para a build de produção e outro separado para testes:
# Dockerfile.testFROM node:18-alpine AS builder
WORKDIR /appCOPY package*.json ./RUN npm ciCOPY tsconfig.json ./COPY src/ ./src/
# Compilação TypeScriptRUN npm run build
# Estágio para testesFROM node:18-alpine AS test-runnerWORKDIR /appCOPY --from=builder /app/dist ./distCOPY --from=builder /app/node_modules ./node_modulesCOPY --from=builder /app/package.json ./COPY tests/ ./tests/COPY jest.config.ts ./
# Execução dos testes de integraçãoCMD ["npx", "jest", "--config", "jest.config.ts", "--testMatch", "**/*.integration.test.ts"]Para gerenciar vários serviços, usamos docker-compose.yml:
version: '3.8'services: app: build: context: . dockerfile: Dockerfile.test depends_on: postgres: condition: service_healthy redis: condition: service_healthy environment: - DB_HOST=postgres - DB_PORT=5432 - REDIS_HOST=redis - REDIS_PORT=6379 volumes: - ./tests:/app/tests:ro networks: - test-network
postgres: image: postgres:15-alpine environment: POSTGRES_DB: testdb POSTGRES_USER: testuser POSTGRES_PASSWORD: testpass healthcheck: test: ["CMD-SHELL", "pg_isready -U testuser -d testdb"] interval: 5s timeout: 5s retries: 5 networks: - test-network
redis: image: redis:7-alpine healthcheck: test: ["CMD", "redis-cli", "ping"] interval: 5s timeout: 3s retries: 5 networks: - test-network
networks: test-network: driver: bridgeEscrevendo testes de integração avançados em TypeScript
Agora, criaremos um teste que verifica um cenário completo: gravação no banco de dados, cache no Redis e envio de evento para a fila. Usaremos a biblioteca testcontainers para gerenciamento dinâmico de contêineres a partir do código TypeScript:
// tests/integration/user-registration.integration.test.tsimport { GenericContainer, StartedTestContainer, Wait } from 'testcontainers';import { PostgreSqlContainer } from '@testcontainers/postgresql';import { RedisContainer } from '@testcontainers/redis';import axi