Por que não rodar migrations SQL em testes, e como isso dobrou a velocidade da suite
Aprofundamento CEVIU
Aprofundamento
O artigo do CEVIU de 1º de junho sobre o branching de bancos de dados no Lakebase da Databricks já apontava para o cerne do problema: 56% dos DBAs ainda gastam horas provisionando ambientes de teste. A solução descrita agora não é só um 'trick' para Go, é a aplicação prática do conceito de database-as-code em escala de desenvolvimento, com duas camadas técnicas críticas que o artigo-fonte detalha bem: primeiro, o uso do backup API do SQLite (não cp) para lidar com WAL, SHM e journal files; segundo, a geração de golden databases por hash SHA256 das migrations, não por timestamp ou versão, isso evita falhas silenciosas quando múltiplas branches contêm scripts conflitantes.
A abordagem elimina o custo de locking sequencial em SQLite (que bloqueia tabelas inteiras durante cada migration), um gargalo que os perfis mostraram ser o principal causador de lentidão real, não o I/O em si, mas a contenção de schema changes. E, diferentemente do que se vê em soluções como o pgdbtemplate (Go, 2025), aqui não há dependência de template pré-construído nem manutenção manual: o golden file é gerado sob demanda, atômico via os.Rename, e isolado por processo, sem lock file, sem race condition funcional.
O que mudou
Em abril, a cobertura CEVIU focou em execução seletiva (Stripe) e caching interval-aware (Netflix), estratégias que reduzem *quantos* testes ou queries rodam. Agora, a mudança é mais profunda: reduz *o que cada teste precisa fazer antes de rodar*. Não é otimização de pipeline, mas de setup. O artigo-fonte confirma que o protótipo inicial com cópia estática de SQLite rendeu 7x, mas a versão final, com hashing dinâmico, backup API e suporte a concorrência, entrega 2.2x na prática. Isso mostra maturação: trocou-se velocidade teórica por robustez operacional, mantendo ganho real sem comprometer correção.
Por que isso importa
Testes que demoram mais de 3 minutos travam o fluxo de desenvolvedor. Um ganho de 2.2x não é só sobre CI mais rápida, é sobre reduzir o tempo entre escrever código e ver feedback, o que impacta diretamente a qualidade das decisões arquitetônicas. Em monorepos Go com múltiplos serviços (como o citado no artigo), essa técnica também melhora a DX ao eliminar flakiness causada por transações aninhadas ou estado compartilhado entre testes. E, ao usar testing.Testing() como guard, ela evita riscos de produção, algo que o branching do Lakebase da Databricks resolve em outro nível, mas com custo de infraestrutura maior.
Linha do tempo
Netflix lança cache interval-aware para Druid, reduzindo carga de queries redundantes.
CEVIU cobre execução seletiva de testes na Stripe para monorepo Ruby de 50 milhões de linhas.
Databricks lança branching de banco de dados no Lakebase com cópias instantâneas.
Publicação da otimização de testes em Go com golden database baseado em hash de migrations.
Perguntas frequentes
Por que não usar transações para resetar o banco entre testes?
Transações mascaram diferenças reais de comportamento: WAL, locking, triggers e isolation levels funcionam diferente dentro de uma transação. O artigo cita explicitamente que isso gera falsos positivos e negativos, especialmente em PostgreSQL. Clonar o banco garante que cada teste roda em um ambiente idêntico ao de produção.
Essa solução funciona com PostgreSQL ou MySQL?
Sim, em teoria, mas exige adaptação. O artigo-fonte diz que cada banco tem sua forma 'quirky' de clonagem. Para PostgreSQL, você usaria CREATE DATABASE ... WITH TEMPLATE ou pg_dump + psql. Para MySQL, mysqldump com --no-data não basta: o esquema completo inclui stored procedures, collations e engine-specific settings, exigindo scripts customizados.
O que acontece se duas threads tentarem criar o golden database ao mesmo tempo?
Ambas executam as migrations, mas apenas uma vence a corrida para renomear o arquivo final com os.Rename. Como o conteúdo é idêntico (hash determinístico), não há corrupção. É trabalho redundante, não errado, e o custo é pago uma vez, não em cada teste.
Como garantir que o golden database nunca fique desatualizado?
Ele nunca fica. O hash SHA256 é calculado sobre o conteúdo bruto de todos os arquivos de migration no diretório. Se um novo script for adicionado, o hash muda, o golden file é reconstruído automaticamente. Não há processo manual de atualização, é pura content addressing.
Fontes
- gaultier.github.iofonte original
- Categoria
- CEVIU Web Dev
- Publicado
- 17 de junho de 2026
- Editoria
- CEVIU Web Dev
