Home Projetos & Releases BigBangcraft Blog Sobre & Carreira
DevOps & Cloud • Hub 6 min de leitura 24 visualizações
Raw .md

O autoengano de emular a AWS na máquina de desenvolvimento

PD

Pedro Dalben

CTO no Integrar Plus • Publicado em 28 de September de 2026

O autoengano de emular a AWS na máquina de desenvolvimento

Toda vez que uma equipe decide que precisa de testes de integração com a nuvem rodando no notebook dos desenvolvedores, o ciclo se repete. Alguém configura um container do LocalStack, descobre que a memória da máquina evaporou, esbarra em recursos bloqueados por licença paga e, meses depois, busca uma alternativa mais leve. O lançamento do Fakecloud reacendeu essa discussão ao prometer compatibilidade com dezenas de serviços da AWS em um único executável, sem a sobrecarga do concorrente histórico. Mas essa promessa ataca o sintoma errado de um problema arquitetural antigo.

Dois extremos e por que ambos erram o alvo

O debate técnico em torno dessas ferramentas costuma se dividir em dois extremos irreconciliáveis. De um lado, defensores do isolamento estrito argumentam que qualquer processo externo na suíte de testes é um erro. Para esse grupo, o caminho correto é adotar o padrão sem entrada e saída ou criar adaptadores próprios com implementações falsas em memória. O argumento central é compreensível: se o teste depende de um processo externo, você perde o controle do estado e assume premissas implícitas, como esperar que uma fila esteja sempre vazia no início de cada cenário. Se o código do domínio não conversa diretamente com a biblioteca da AWS, bastam dois adaptadores para resolver a equação, um em memória para a suíte local e outro concreto para produção.

Do outro lado da mesa, engenheiros com cicatrizes de produção apontam que simulações em memória ignoram o propósito dos testes de integração. Testar contra uma imitação não ensina nada sobre o serviço real. A AWS tem peculiaridades de rede, limites de taxa, regras de permissões e comportamentos de consistência eventual que nenhum simulador em memória replica. A conclusão dessa corrente é radical: se você quer testar integração com filas ou armazenamento, use a própria nuvem para provisionar recursos temporários reais durante o pipeline, já que filas e buckets sobem em frações de segundo.

Eu discordo das duas abordagens quando aplicadas como regra geral, e discordo com ainda mais força de quem tenta resolver esse dilema instalando emuladores locais.

O pior dos dois mundos em um container

Emuladores como LocalStack ou Fakecloud entregam o pior dos dois mundos. Eles trazem a lentidão, o consumo de recursos e a fragilidade de configuração de um teste de integração real, combinados com a falsidade e a superficialidade de uma imitação imperfeita.

O primeiro problema é a ilusão de paridade. Quando um projeto afirma ter cobertura de cem por cento de dezenas de serviços da AWS, qualquer inspeção mais detalhada no código fonte revela a realidade. Serviços como DynamoDB ou Kinesis possuem detalhes de concorrência, paginação e latência que a própria Amazon tem dificuldade de padronizar entre regiões. O próprio simulador local oficial de DynamoDB distribuído pela AWS mascara comportamentos clássicos de consistência eventual que só quebram quando o sistema atinge tráfego real. Esperar que um emulador mantido por equipes pequenas acompanhe as atualizações de esquema e as nuances operacionais de cada serviço é ingenuidade. Você gasta tempo depurando divergências do emulador em vez de testar a lógica do seu produto.

O segundo problema é a degradação do ciclo de desenvolvimento. Uma suíte de testes de unidade precisa rodar em segundos para permitir iteração rápida. No momento em que você exige que cada engenheiro execute containers simulando filas, tópicos e bancos NoSQL para passar a suíte local, o comando de teste deixa de ser executado com frequência. A suíte fica pesada, conexões locais falham por portas presas ou processos zumbis, e a manutenção do ambiente local passa a consumir horas da semana.

A alternativa prática: desacoplamento e testes pontuais

Na arquitetura que opero no Integrar Plus, rodando Ruby on Rails sobre servidores próprios, a separação precisa ser mais direta. Se um componente precisa armazenar arquivos, ele conversa com uma camada de abstração. No ecossistema Rails, o Active Storage resolve isso isolando o driver de disco local nos testes e o driver de nuvem na produção. O teste automatizado de unidade valida a lógica de negócio do sistema: se o anexo foi vinculado, se a transação do banco de dados fechou corretamente e se o estado do modelo mudou conforme o esperado. O teste não precisa comprovar que a API da Amazon consegue receber bytes e salvá-los no disco dela.

Quando criamos serviços que dependem de integrações externas, definimos interfaces deliberadas na própria aplicação:

class DocumentStorage
  def initialize(adapter: default_adapter)
    @adapter = adapter
  end

  def store(file_id, content)
    @adapter.write("documents/#{file_id}", content)
  end

  private

  def default_adapter
    Rails.env.test? ? InMemoryStorage.new : S3Storage.new
  end
end

Quando a lógica depende diretamente de contratos específicos da nuvem, como a assinatura de URLs temporárias ou políticas refinadas de expiração, a verificação deve acontecer em outra camada. Nesses casos, manter um conjunto pequeno de testes sintéticos executados apenas no pipeline de integração contínua, apontando para recursos descartáveis em uma conta isolada da própria nuvem, é muito mais barato do que tentar simular a infraestrutura no laptop.

Abordagem Velocidade local Fidelidade de comportamento Custo de manutenção
Emulador local (Fakecloud ou LocalStack) Baixa Falsa segurança Alto
Fakes em memória (interfaces desacopladas) Alta Baixa para a nuvem Baixo
Recursos reais descartáveis no CI Muito baixa Alta Médio
Adaptador com testes de contrato no CI Alta no loop diário Alta onde importa Baixo

Existem diretrizes práticas para evitar o atrito desnecessário:

  • Deixe o loop local rápido confiando em contratos e adaptadores simples.
  • Valide regras de domínio sem encostar em rede externa nem subir containers secundários.
  • Concentre a validação contra a API real da nuvem em testes pontuais de contrato durante o deploy.
  • Rejeite a tentação de replicar a infraestrutura inteira de um provedor dentro da sua máquina de trabalho.

A promessa de rodar toda a nuvem dentro do seu computador vende bem porque promete conforto sem mudança de arquitetura. O preço que ninguém calcula na largada é passar semanas caçando diferenças entre o comportamento do simulador e o da API de verdade. A nuvem não cabe no notebook, e fingir o contrário só transfere a complexidade da infraestrutura para dentro da sua suíte de testes.

Fontes

PD

Sobre Pedro Dalben

CTO e arquiteto full stack especializado em Ruby on Rails, Vue.js, sistemas multi-tenant e infraestrutura distribuída.