Contexto e Requisitos
Equipes de desenvolvimento frequentemente necessitam de testes de integração que dependem de serviços intermediários, como bancos de dados MySQL ou sistemas de mensageria como RabbitMQ. Cada desenvolvedor deve ser capaz de escrever e executar testes para seu código de forma independente.
Para evitar interferências mútuas, é comum configurar ambientes locais. No entanto, isso deve ser rápido, simples e permitir uma limpeza eficiente após o uso.
Empregando Docker para Provisionamento de Ambientes
O Docker atende bem a esses requisitos, mas apresenta desafios adicionais:
- Instalação local trabalhosa: Cada desenvolvedor precisa instalar o Docker, o que pode ser um obstáculo, particularmente em redes restritas ou em sistemas Windows que requerem conectividade para a instalação.
- Desempenho comprometido dos testes: Quando há muitas dependências, o Docker local pode consumir recursos significativos e impactar a velocidade de execução.
- Dificuldade em múltiplos ambientes: Como os testes dependem do Docker local, rodá-los em ambientes como Jenkins exige a instalação do Docker em cada infraestrutura.
Em suma, apesar de o Docker simplificar o provisionamento de dependências, a dependência local restringe a portabilidade dos testes entre diferentes ambientes.
Otimizando Testes com um Servidor Docker Centralizado
O Docker suporta modos de conexão remota, o que permite implantar um servidor Docker centralizado. Os testes de integração podem então se coenctar via TCP para gerenciar containers, eliminando a necessidade de instalação local do Docker.
Configuração do Servidor Docker Remoto
Para configurar um servidor Docker remoto em uma máquina CentOS 7.6, execute os seguintes passos:
- Modifique o arquivo
/etc/docker/daemon.jsonpara ativar a porta remota: ``` {"hosts": ["tcp://0.0.0.0:2376", "unix:///var/run/docker.sock"]} - Crie o arquivo
/etc/systemd/system/docker.service.d/override.confcom este conteúdo: ``` [Service] ExecStart= ExecStart=/usr/bin/dockerd - Recarregue o daemon do systemd:
systemctl daemon-reload - Reinicie o serviço Docker:
systemctl restart docker.service
Framework Testcontainers
Após a configuração do servidor remoto, surgem questões sobre como conectá-lo no código, evitar conflitos de porta entre desenvolvedores e limpar containers após o uso. O framwork Testcontainers resolve esses problemas:
-
Integra-se com JUnit 4 e JUnit 5 para iniciar e parar containers. A cada execução de teste, novos containers são iniciados com portas dinâmicas, garantindo isolamento entre desenvolvedores.
-
Utiliza o componente testcontainers/ryuk para limpar containers após um tempo configurado.
- Todas essas operações são transparentes para o usuário.
Integração com Spring Boot
A empresa Playtika disponibiliza um framework que integra Testcontainers com Spring Boot, acessível em testcontainers-spring-boot, facilitando testes em aplicações Spring.
Variáveis de Ambiente
Para usar Testcontainers ou testcontainers-spring-boot com Docker remoto, não é necessário instalar o cliente Docker local. Em vez disso, configure variáveis de ambiente para o endereço do servidor remoto:
- Opção 1: Definir a variável de sistema
DOCKER_HOST=tcp://endereco_ip_servidor:2376 - Opção 2: No código Java, antes de instanciar o container, usar
System.setProperty("DOCKER_HOST","tcp://endereco_ip_servidor:2376") - Opção 3: Configurar a variável de ambiente no plugin Maven Failsafe, se aplicável.
Gerenciamento via Linha de Comando
Para administrar o Docker remotamente via linha de comando, instale clientes Docker adequados. Instruções de instalação para diversos sistemas operacionais estão disponíveis neste gist.
Referências