Introdução: por que Docker e Swift são a combinação ideal para testes de integração?
\n\nO desenvolvimento moderno para iOS e macOS exige não apenas testes unitários, mas também testes de integração completos. Quando sua aplicação interage com um banco de dados, APIs externas ou sistema de arquivos, testar cada componente de forma isolada já não é suficiente. É aqui que o Docker entra em ação.
\n\nO Docker permite criar ambientes idênticos para testes, eliminando o problema de "funciona na minha máquina". Para desenvolvedores Swift, isso é especialmente relevante: a conteinerização permite testar aplicações Swift do lado do servidor (Vapor, Kitura), bem como emular a infraestrutura para aplicações iOS (bancos de dados, caches, filas de mensagens).
\n\nNeste artigo, abordaremos o ciclo completo de configuração de testes de integração Swift com Docker: desde a criação do ambiente de teste até a execução em CI/CD.
\n\n1. Preparação do ambiente: Docker e Swift
\n\n1.1. Instalação do Docker e Swift Toolchain
\n\nAntes de tudo, certifique-se de ter instalado:
\n- \n
- Docker Desktop (para macOS) ou Docker Engine (para Linux) \n
- Swift Toolchain versão 5.7+ (pode ser baixado em swift.org) \n
- Xcode 14+ (se estiver testando componentes iOS) \n
1.2. Criação do Dockerfile para Swift
\n\nVamos começar criando uma imagem Docker básica para nossa aplicação Swift. Crie um arquivo Dockerfile na raiz do projeto:
# Dockerfile\nFROM swift:5.9-focal AS base\n\n# Define o diretório de trabalho\nWORKDIR /app\n\n# Copia os arquivos do manifesto Package.swift\nCOPY Package.swift ./\nCOPY Sources/ ./Sources/\nCOPY Tests/ ./Tests/\n\n# Compila o projeto\nRUN swift build -c debug\n\n# Imagem final para testes\nFROM base AS test\nCMD ["swift", "test", "--parallel"]\n\n\nEsta imagem compila o projeto e executa os testes. Para testes de integração, precisaremos de serviços adicionais.
\n\n2. Testes de integração com Docker Compose
\n\nO Docker Compose permite executar vários contêineres simultaneamente. Para um cenário típico, precisaremos de:
\n- \n
- Um contêiner com nossa aplicação Swift \n
- Um contêiner com PostgreSQL (ou outro banco de dados) \n
- Um contêiner com Redis (para cache) \n
2.1. Exemplo de docker-compose.yml
\n\n# docker-compose.yml\nversion: '3.8'\n\nservices:\n postgres:\n image: postgres:15\n environment:\n POSTGRES_USER: test_user\n POSTGRES_PASSWORD: test_pass\n POSTGRES_DB: test_db\n ports:\n - "5432:5432"\n healthcheck:\n test: ["CMD-SHELL", "pg_isready -U test_user -d test_db"]\n interval: 5s\n timeout: 5s\n retries: 5\n\n redis:\n image: redis:7-alpine\n ports:\n - "6379:6379"\n\n swift-tests:\n build:\n context: .\n dockerfile: Dockerfile.test\n depends_on:\n postgres:\n condition: service_healthy\n redis:\n condition: service_started\n environment:\n DATABASE_URL: "postgres://test_user:test_pass@postgres:5432/test_db"\n REDIS_URL: "redis://redis:6379"\n volumes:\n - .:/app\n\n\n2.2. Dockerfile especial para testes
\n\nVamos criar um Dockerfile.test que aguardará a disponibilidade das dependências:
# Dockerfile.test\nFROM swift:5.9-focal\n\nWORKDIR /app\n\n# Instala netcat para verificar conexões\nRUN apt-get update && apt-get install -y netcat-openbsd && rm -rf /var/lib/apt/lists/*\n\nCOPY Package.swift ./\nRUN swift package resolve\n\nCOPY . .\n\n# Aguarda PostgreSQL e Redis\nCOPY wait-for-services.sh /usr/local/bin/\nRUN chmod +x /usr/local/bin/wait-for-services.sh\n\nCMD ["wait-for-services.sh"]\n\n\nScript wait-for-services.sh:
#!/bin/bash\n# wait-for-services.sh\n\necho "Aguardando PostgreSQL..."\nwhile ! nc -z postgres