dbt em produção: 12 testes que evitam incidentes (com critérios de severidade)

Por que testes em produção falham na vida real

Em produção, incidentes raramente acontecem apenas porque “o SQL quebrou”. Na prática, o que quebra dashboards de verdade é a falta de qualidade mínima nos dados.

Isso aparece de várias formas:

  • chaves que passam a vir nulas;
  • duplicidades que inflam métricas;
  • relacionamentos que deixam de bater;
  • valores fora do domínio do negócio;
  • datas fora do intervalo esperado;
  • fatos sem dimensões e dimensões sem fatos.

 

O dbt já nasce com testes genéricos que cobrem boa parte do básico, como not_null, unique, accepted_values e relationships. No entanto, existe uma diferença importante entre um projeto que “tem testes” e um projeto que realmente evita incidentes.

Essa diferença está em três decisões:

  1. definir qualidade mínima por camada, como staging, core e mart;
  2. definir severidade, separando o que quebra o pipeline do que apenas gera alerta;
  3. controlar ruído para não criar alert fatigue.

Em outras palavras, testar tudo não significa proteger melhor a operação. O que importa é testar o que realmente pode quebrar decisões, dashboards e confiança.

Padrão de qualidade mínima por camada

Antes de criar dezenas de testes, defina o papel de cada camada do seu projeto. Dessa forma, os testes deixam de ser aleatórios e passam a seguir uma lógica de qualidade.

Camada 1: staging

Na camada de staging, o objetivo é garantir que o dado está utilizável e que você não está propagando sujeira para as próximas etapas.

Por isso, foque em:

  • integridade de campos;
  • valores nulos em colunas críticas;
  • domínios esperados;
  • chaves técnicas;
  • tipos de dados coerentes;
  • datas dentro de intervalos possíveis.

Nesse ponto, o teste não precisa validar toda a regra de negócio. Ainda assim, ele precisa impedir que dados claramente inválidos avancem no pipeline.

Camada 2: core

Na camada core, o objetivo é garantir que o dado está coerente com o modelo.

Aqui, entram com mais força os testes de chaves estáveis, unicidade e relacionamentos. Afinal, essa camada normalmente sustenta modelos reutilizáveis, regras padronizadas e joins que serão consumidos por vários marts.

Por isso, testes como relationships e unique são fundamentais para evitar duplicidades, quebras de joins e inconsistências estruturais.

Camada 3: mart

Na camada de mart, o objetivo é proteger o consumo final.

Nesse caso, os testes precisam garantir que dashboards não quebrem e que as métricas não “mintam” por falhas simples. Portanto, além dos testes genéricos, entram testes de regra de negócio, coerência entre tabelas, completude por período e anomalias relevantes.

Na prática, é nessa camada que o impacto fica mais visível para áreas de negócio. Por isso, qualquer falha crítica deve ter severidade bem definida.

Severidade em produção: quando falhar pipeline vs apenas alertar

No dbt, a severidade de testes normalmente é tratada como error ou warn. Além disso, você pode configurar como lidar com warnings no processo, inclusive promovendo alguns alertas para erro quando fizer sentido.

O ponto principal é não tratar todas as falhas da mesma forma. Afinal, nem todo problema de qualidade tem o mesmo impacto operacional.

Uma forma prática de organizar isso é mapear os testes em P0, P1 e P2.

P0: quebra o pipeline

P0 representa falhas que deixam o dado inutilizável ou geram alto risco de decisão errada em massa.

Alguns exemplos são:

  • chave primária nula;
  • duplicidade em chave de fato;
  • relacionamento quebrado com dimensão crítica;
  • tabela executiva sem dados do dia;
  • métrica financeira com regra estrutural inválida.

Nesse caso, o pipeline deve falhar. Caso contrário, o time corre o risco de entregar dado errado com aparência de dado confiável.

P1: alerta forte, mas não quebra por padrão

P1 representa falhas que degradam a qualidade, mas não invalidam todo o dataset.

Alguns exemplos são:

  • accepted_values fora do padrão em 1% ou 2% das linhas;
  • atraso moderado de freshness;
  • outliers relevantes, mas ainda explicáveis;
  • pequenas inconsistências em campos não estruturais.

Nesses casos, o time precisa ser avisado. No entanto, nem sempre faz sentido bloquear toda a entrega.

P2: monitoramento silencioso ou digest periódico

P2 representa sinais fracos, regras experimentais ou indicadores que você quer acompanhar em tendência.

Alguns exemplos são:

  • pequenas variações de distribuição;
  • campos auxiliares fora do padrão;
  • regras novas ainda em fase de calibração;
  • alertas de baixa criticidade.

Portanto, P2 não deve gerar interrupção imediata. Em geral, faz mais sentido consolidar esses sinais em um digest diário ou semanal.

A regra de ouro para evitar alert fatigue é simples: gere alerta imediato apenas para P0 e P1 que afetam colunas críticas. O restante deve virar acompanhamento periódico.

As 12 verificações que mais evitam incidentes em dashboards

Abaixo está um conjunto enxuto e realmente útil de verificações. Os quatro primeiros testes são genéricos do dbt. Já os demais combinam regras de negócio, confiabilidade operacional e boas práticas para produção.

1. not_null em chaves críticas

Use not_null em ids, datas-chave e colunas necessárias para joins e agregações.

Esse teste é especialmente importante porque valores nulos em chaves críticas costumam quebrar relacionamentos, distorcer métricas e gerar linhas órfãs.

Onde aplicar:

  • staging: campos essenciais da origem;
  • core: chaves do modelo;
  • mart: campos que sustentam métricas e filtros de dashboard.

Se uma chave crítica vem nula, normalmente o caso deve ser tratado como P0.

2. unique na chave do grão correto

O teste unique evita duplicidade silenciosa, um dos problemas mais perigosos em Analytics.

Por exemplo, se uma tabela deveria ter uma linha por pedido_id, duplicar esse grão pode inflar receita, pedidos, conversão e outras métricas.

No entanto, aplicar unique na coluna errada é pior do que não aplicar. Antes de criar o teste, valide qual é o grão correto da tabela.

Em geral, esse teste deve ser P0 quando protege uma tabela de fato, uma dimensão crítica ou uma métrica executiva.

3. relationships para integridade referencial

O teste relationships garante que fatos apontem para dimensões existentes.

Em outras palavras, ele ajuda a responder: todo pedido tem cliente? Toda venda tem produto? Todo evento aponta para uma entidade válida?

Esse tipo de teste reduz o risco de joins quebrados, registros órfãos e métricas incompletas.

Em marts, relacionamento quebrado com dimensão crítica costuma ser P0. Em camadas intermediárias ou dimensões menos sensíveis, pode ser P1.

4. accepted_values em colunas categóricas

O teste accepted_values funciona muito bem para campos como status, tipo, canal, país, moeda e categoria.

Ele evita que valores inesperados entrem silenciosamente nos dashboards. Além disso, ajuda a detectar mudanças na origem, erros de digitação, novos códigos não mapeados ou problemas de integração.

Em dados de origem instáveis, comece como P2. Depois, quando o domínio estiver mais estável, promova para P1.

5. Intervalos válidos para datas e números

Nem todo teste importante vem pronto como genérico padrão. Ainda assim, muitos deles são simples de criar como testes singulares em SQL.

Alguns exemplos:

  • datas no futuro em eventos históricos;
  • valores negativos em receita;
  • quantidade absurda em pedidos;
  • idade fora de intervalo plausível;
  • desconto maior que o total da compra.

Esses testes conectam qualidade técnica com regra de negócio. Por isso, a severidade pode variar entre P0 e P1, dependendo da coluna e do impacto.

6. Monotonicidade ou consistência de datas de atualização

Datas inconsistentes podem indicar regressão em pipeline incremental, erro de carga ou problema de origem.

Um exemplo simples: updated_at não deveria ser menor que created_at.

Esse tipo de regra evita que dados “voltem no tempo” sem explicação. Além disso, ajuda a detectar falhas em processos incrementais, merges e atualizações parciais.

Na maioria dos casos, esse teste entra como P1. Porém, se a coluna sustenta lógica de atualização crítica, ele pode virar P0.

7. Grão do fato consistente

Toda tabela de fato precisa ter um grão claro.

Por exemplo: uma tabela de pedidos deve ter uma linha por pedido_id. Já uma tabela de itens de pedido deve ter uma linha por combinação de pedido_id e item_id.

Quando o grão não está claro, duplicidades aparecem, joins explodem e KPIs deixam de ser confiáveis.

Mesmo que você não use unique diretamente, valide o grão com contagens, agrupamentos e checagens específicas. Em tabelas críticas, esse teste deve ser P0.

8. Completude mínima por período

Dashboards também quebram quando a carga simplesmente não entrega dados.

Por isso, crie testes de completude mínima por período. Alguns exemplos:

  • todo dia deve ter pelo menos X registros;
  • uma tabela não pode zerar do nada;
  • uma partição esperada precisa existir;
  • uma data recente precisa estar presente no mart.

Esse teste ajuda a detectar falhas de carga antes que o consumidor final perceba. Normalmente, ele entra como P1, mas pode ser P0 em dashboards executivos ou rotinas críticas.

9. Regra de negócio de soma e coerência

Testes de coerência validam se os números fazem sentido dentro da lógica do negócio.

Alguns exemplos:

  • total = subtotal + frete − desconto;
  • imposto não pode ser maior que total;
  • margem deve estar dentro de limites plausíveis;
  • quantidade entregue não pode ser maior que quantidade vendida;
  • receita líquida não deve ultrapassar receita bruta.

Essas regras evitam incidentes difíceis de perceber apenas olhando schema ou nulos. Como resultado, protegem a interpretação das métricas, não apenas a estrutura dos dados.

Em geral, essas validações entram como P1. No entanto, podem ser P0 quando afetam métricas financeiras ou indicadores executivos.

10. Consistência entre tabelas

Nem todo problema aparece dentro de uma única tabela. Muitas vezes, o erro surge quando duas camadas deixam de bater.

Por exemplo: o número de pedidos no mart deve bater com os fatos filtrados no core dentro de uma tolerância aceitável.

Esse teste é útil para identificar perdas de registros, filtros indevidos, joins mal aplicados e diferenças entre regras de transformação.

Portanto, sempre que um mart consolidar informações críticas, compare o resultado com a camada anterior.

11. Testes em colunas críticas priorizadas

Este ponto é mais uma estratégia do que um teste específico.

Você não precisa testar tudo. Pelo contrário, tentar testar todas as colunas pode gerar ruído, custo e baixa manutenção.

O melhor caminho é escolher um conjunto pequeno de colunas críticas por domínio. Em seguida, eleve a severidade nessas colunas.

Priorize:

  • chaves;
  • datas;
  • status;
  • valores financeiros;
  • colunas usadas em filtros de dashboard;
  • campos que entram em regras de métricas;
  • atributos usados em joins críticos.

Dessa forma, o time concentra esforço onde a falha realmente quebra decisão.

12. store_failures para investigação rápida

Quando um teste falha, o time precisa descobrir rapidamente quais linhas causaram o problema.

Para isso, o dbt permite armazenar falhas de teste com store_failures. Assim, em vez de reconstruir tudo manualmente, você consegue acessar os registros problemáticos com mais agilidade.

Essa prática melhora o tempo de resposta a incidentes. Além disso, ajuda a criar runbooks, ajustar regras e discutir problemas com times de origem.

Em testes críticos, store_failures costuma ser um recurso operacional muito valioso.

Como evitar alert fatigue sem reduzir qualidade

Alert fatigue aparece quando o time recebe alertas demais e passa a ignorar todos eles. Para evitar esse problema, a solução não é reduzir qualidade. Pelo contrário, é melhorar a governança dos alertas.

1. Comece por 5 a 10 tabelas críticas

Não tente testar o projeto inteiro no primeiro ciclo.

Comece pelos dashboards principais, métricas executivas e tabelas que realmente influenciam decisão. Assim, você gera valor rápido e evita criar um volume grande de alertas sem maturidade operacional.

2. Escolha colunas críticas por tabela

Depois de escolher as tabelas, selecione as colunas mais importantes.

Normalmente, isso inclui chaves, datas, status, valores financeiros e campos usados em filtros de dashboard.

Com essa priorização, os testes ficam mais relevantes e o time entende melhor por que cada alerta existe.

3. Use poucos alertas, mas bem roteados

Alertas precisam chegar no canal certo e na severidade certa.

Um padrão simples funciona bem:

  • P0 quebra pipeline e abre incidente;
  • P1 alerta em canal visível, mas não trava entrega por padrão;
  • P2 entra em digest diário ou semanal.

Dessa maneira, o time reage rápido ao que importa e acompanha o restante sem interrupção constante.

4. Ajuste falsos positivos com rotina

Todo teste novo pode gerar ruído no começo. Por isso, trate a implantação como rollout gradual.

Se um teste dispara alerta sem impacto real, ajuste a regra, a tolerância ou a severidade. Caso contrário, o time deixa de confiar no sistema de qualidade.

Rollout gradual: como colocar testes em produção sem dor

Colocar testes em produção exige sequência. Assim, o time aprende, reduz falsos positivos e aumenta a cobertura sem travar a operação.

Fase 1: base mínima

Comece com not_null, unique e relationships nas tabelas críticas.

Nessa fase, seja agressivo em P0 apenas onde a quebra é real. Em outras palavras, só faça o pipeline falhar quando o dado realmente ficar inutilizável ou perigoso para consumo.

Fase 2: domínio e regras de negócio

Depois da base mínima, adicione accepted_values e regras específicas de negócio.

Aqui, vale começar com severidade mais baixa para medir falsos positivos. À medida que o teste estabiliza, você pode promover a severidade.

Dessa forma, o time evita bloquear entregas por regras ainda imaturas.

Fase 3: operacionalização

Por fim, ative store_failures para testes críticos e garanta rastreabilidade de incidentes.

Além disso, defina quem recebe alertas, onde os problemas serão registrados e como o time revisará ruídos.

A cada mês, reavalie quais testes evitaram incidentes e quais apenas fizeram barulho. Com isso, a suíte de testes melhora continuamente.

Checklist final para produção

Antes de considerar seus testes prontos para produção, valide:

  • qualidade mínima definida por camada, como staging, core e mart;
  • P0, P1 e P2 definidos com base em impacto de negócio;
  • colunas críticas priorizadas;
  • warnings tratados com política clara no pipeline;
  • falhas investigáveis com store_failures em testes críticos;
  • alertas roteados para o time certo;
  • rotina de revisão para falsos positivos;
  • documentação mínima para regras de negócio críticas.

Conclusão

dbt em produção não é sobre ter muitos testes. É sobre ter os testes certos, com a severidade certa, nas colunas certas.

Quando você combina qualidade mínima por camada, critérios de P0, P1 e P2, colunas críticas priorizadas e rollout gradual, os testes deixam de ser apenas uma formalidade técnica. Como resultado, passam a proteger dashboards, métricas e decisões de negócio.

Na prática, esse padrão de 12 verificações ajuda o time a sair do modo “apagar incêndio” e entrar no modo “qualidade mínima garantida”. Além disso, reduz ruído operacional, melhora a confiança nos dados e torna os incidentes mais fáceis de investigar quando eles aparecem.

Pesquisar

Posts Recentes

Categorias