Pular para o conteúdo
Engenharia

Code Review que Salva Vidas: Boas Praticas

Code review de verdade vai muito alem de checar formatacao e naming conventions. Em sistemas criticos, um review mal feito pode custar vidas. Aqui estao as tecnicas que

Em junho de 1996, o Ariane 5 explodiu 37 segundos apos o lancamento. O bug estava em codigo reaproveitado do Ariane 4. Codigo que passou por anos de revisao e operacao bem-sucedida. O problema e que ninguem revisou as suposicoes do codigo antigo quando o contexto mudou.

Se voce quer a historia completa, leia A Historia Nao Contada do Desastre do Ariane 5. Aqui vou falar sobre o que um code review adequado teria capturado, e como estruturar reviews que realmente encontram bugs antes que causem dano.

Code review nao e so checar se o nome da variavel e descritivo. Em sistemas que importam, review e um processo de engenharia com tecnicas especificas, ferramentas e uma cultura que a maioria das equipes nao tem.

O Que o Review do Ariane 5 Nao Fez

O codigo do sistema de navegacao inercial foi reutilizado do Ariane 4 sem revisao das suposicoes de negocio. A suposicao que quebrou: a velocidade horizontal do foguete nunca excederia 32.767 (o limite de um int16). No Ariane 4, isso era verdade. No Ariane 5, muito mais potente, nao era.

Um review que perguntasse 'quais sao as suposicoes de range desse codigo e elas ainda sao validas nesse contexto?' teria encontrado o problema. Um review que verificasse 'o que acontece quando esse valor excede o tipo?' teria encontrado o problema.

Mas a maioria dos reviews nao faz essas perguntas. Revisores olham para o codigo e perguntam 'isso parece razoavel?'. Codigo legado que funcionou por anos parece muito razoavel.

As tres perguntas que o review deveria ter feito

Code Review que Salva Vidas: Boas Praticas. Code review de verdade vai muito alem de checar formatacao e naming conventions. Em sistemas criticos, um review mal feito pode custar vidas. Aqui estao as tecnicas que fazem diferenca real.

Os Niveis de Code Review

Nao existe um unico tipo de code review. Diferentes tecnicas encontram diferentes tipos de problemas. Equipes que fazem so uma delas ficam cegas para categorias inteiras de bugs.

Nivel 1: Review de estilo e convencao

Esse e o review que todo mundo faz e acha que e suficiente. Formatacao, naming, documentacao. E o menos valioso para encontrar bugs serios, mas o mais facil de automatizar.

Regra de ouro: tudo que pode ser verificado automaticamente por uma ferramenta nao deve consumir tempo humano no review. Use linters, formatters e analisadores estaticos para esse nivel. Libere o revisor humano para pensar.

Nivel 2: Review de logica e correcao

Aqui e onde a maioria das equipes para. O revisor le o codigo e pensa 'isso parece certo?'. E melhor que nada, mas depende muito da experiencia e atencao do revisor no momento.

Nivel 3: Review adversarial

O revisor ativamente tenta encontrar como o codigo pode falhar. Pensa como um atacante ou como Murphy: se algo pode dar errado, o que acontece? Esse nivel de review e o que diferencia equipes mediocres de equipes que produzem software confiavel.

  1. Qual e o valor mais extremo possivel para cada input? O codigo trata esse caso?
  2. E possivel ter input nulo ou vazio onde nao e esperado?
  3. Se esta funcao e chamada em paralelo por duas threads, o que acontece?
  4. O que acontece se o banco de dados retornar erro no meio de uma operacao de multiplos passos?
  5. Ha alguma suposicao de ordem de chamada que nao esta documentada?
  6. Se eu adicionar um zero a esse numero (overflow), o sistema falha de forma perigosa ou segura?

Nivel 4: Review formal e verificacao

Em sistemas criticos como avionics, defesa e medicina, review informal nao e suficiente. A industria usa review formal com checklists estruturados, multiplos revisores independentes, e em alguns casos verificacao matematica via model checking ou SPARK.

Analise Estatica: Seu Revisor Automatico 24/7

Analise estatica examina o codigo sem executar. Encontra categorias inteiras de bugs que reviewers humanos frequentemente perdem porque o codigo 'parece certo'.

  1. SonarQube/SonarCloud: analisa mais de 25 linguagens, integra com CI/CD, detecta code smells, vulnerabilidades e bugs. Tem versao gratuita para projetos open-source.
  2. semgrep: analise semantica que entende o codigo em vez de so fazer pattern matching. Muito util para regras customizadas de seguranca.
  3. CodeQL (GitHub): cria um banco de dados do seu codigo e executa queries. Particularmente poderoso para encontrar vulnerabilidades de seguranca.
  4. Coverity/Synopsys: ferramenta comercial com taxa de falso-positivo muito baixa. Padrao da industria em aeroespacial e automotivo.
  5. clang-analyzer e clang-tidy (C/C++): analise estatica gratis e muito boa incluida no toolchain LLVM.
  6. cargo clippy (Rust): linter com centenas de verificacoes que vao muito alem de estilo.
  7. ESLint + plugins de seguranca (JS/TS): com plugins como eslint-plugin-security e no-secrets, detecta problemas comuns.

Analise estatica nao substitui review humano

Ferramentas encontram: null dereferences, resource leaks, integer overflows, race conditions obvias, SQL injection, XSS.

Ferramentas NAO encontram: logica de negocio incorreta, suposicoes invalidas sobre o dominio, comportamento emergente em sistemas distribuidos, casos de borda especificos do produto.

Testes de Mutacao: Medindo a Qualidade dos Testes

Testes de mutacao sao uma tecnica poderosa que a maioria das equipes nunca usou. A ideia e simples: introduza bugs intencionais no codigo e verifique se seus testes os detectam.

Se voce tem 90% de coverage mas seus testes nao detectam mutacoes simples como trocar '+' por '-' ou '<' por '<=', seus testes nao estao verificando a logica correta.

typescript
// Codigo original
function calculateDiscount(price: number, isPremium: boolean): number {
    if (isPremium && price > 100) {
        return price * 0.9;  // 10% desconto
    }
    return price;
}

// Mutante 1: operador logico trocado
// if (isPremium || price > 100)  <- teste deveria detectar isso

// Mutante 2: operador de comparacao trocado
// if (isPremium && price >= 100)  <- teste deveria detectar isso

// Mutante 3: constante trocada
// return price * 0.8;  <- teste deveria detectar isso

// Se seus testes nao matam esses mutantes, o coverage e uma ilusao.

Ferramentas de mutation testing: Pitest para Java, Stryker para JavaScript/TypeScript, mutmut para Python, cargo-mutants para Rust. Integrar mutation testing no CI e um sinal claro que a equipe leva qualidade a serio.

Pair Programming como Review Continuo

Pair programming e o unico processo de desenvolvimento onde review acontece em tempo real. Um programador escreve, o outro revisa constantemente. Bugs sao capturados antes de existir no repositorio.

Estudos da Universidade de Utah mostram que pair programming reduz defeitos em 15% a 50% dependendo do dominio, com custo de tempo adicional de 15% (nao 100% como muitos supõem). Para sistemas criticos, essa troca e muito favoravel.

Quando pair programming faz mais sentido

  1. Codigo novo em areas de alto risco: algoritmos de seguranca, processamento financeiro, controle de hardware.
  2. Debug de problemas dificeis: dois cerebros pensando de angulos diferentes resolvem mais rapido.
  3. Transferencia de conhecimento: novo membro da equipe trabalhando com senior em codigo critico.
  4. Decisoes de arquitetura que afetam o sistema inteiro.
  5. Qualquer codigo que, se estiver errado, seja muito caro de corrigir em producao.

O Checklist de Review para Software Critico

Checklists existem por uma razao: pilotos de aviao usam checklists antes de cada voo nao porque sao ruins, mas porque a memoria humana e falha e checklists compensam isso. O mesmo vale para code review.

Checklist de review: categorias obrigatorias

Correcao: o codigo faz o que a especificacao diz? Para todos os inputs possiveis?

Casos de borda: null, vazio, zero, valores negativos, valores no limite do tipo, concorrencia.

Tratamento de erro: todos os caminhos de erro sao tratados? O sistema falha de forma segura?

Suposicoes: quais suposicoes o codigo faz? Essas suposicoes sao validas e documentadas?

Seguranca: ha inputs que podem ser controlados por usuarios externos? Validacao presente?

Performance: ha loops aninhados, queries N+1, ou operacoes O(n^2) em caminhos quentes?

Testabilidade: o codigo e testavel? Existem testes adequados para o novo comportamento?

Para sistemas com requisitos de seguranca formal (aviacao, medicina, automotivo), o checklist e muito mais extenso e o processo inclui geralmente duas ou mais revisoes independentes por pessoas que nao tiveram contato previo com o codigo.

A Cultura Por Tras do Review

Tecnicas e ferramentas sao o facil. A parte dificil de code review e cultural. Times que tem medo de conflito fazem review superficial. Times competitivos usam review para mostrar que sabem mais que o autor. Nenhum dos dois funciona.

Review saudavel pressupoe que bugs sao inevitaveis e o objetivo e encontra-los antes que causem dano, nao atribuir culpa. O codigo que e revisado pertence a equipe, nao ao autor. Comentarios sao sobre o codigo, nunca sobre a pessoa.

  1. Revisar codigo nao e o objetivo, e um processo para atingir qualidade. Se analise estatica encontra o bug antes do review humano, isso e excelente.
  2. PRs pequenos sao mais faceis de revisar com qualidade. Incentive commits frequentes e PRs menores.
  3. Deixe claro a diferenca entre bloqueios (bugs reais) e sugestoes (melhorias de estilo). Muitos times bloqueiam PRs por sugestoes cosmeticas.
  4. Reserve tempo real para review. Review apressado entre reunioes nao e review.
  5. Documente as decisoes de design em comentarios ou PRs. Contexto ajuda futuros revisores.
  6. Postmortems blameless: quando um bug passa pelo review, analise o processo, nao a pessoa.

O Ariane 5 falhou em parte porque a cultura de reusar codigo proven era mais forte que a cultura de questionar suposicoes. Um time que pergunta 'por que isso funciona?' em vez de 'isso parece certo?' teria feito as perguntas certas. A historia completa em A Historia Nao Contada do Desastre do Ariane 5 mostra como decisoes culturais e organizacionais contribuiram tanto quanto o bug tecnico.

Perguntas frequentes

Code review realmente previne bugs serios?

Sim, mas depende da qualidade do review. Estudos do IBM mostram que code review encontra entre 60% e 90% dos defeitos quando feito de forma estruturada. O problema e que a maioria das equipes faz review superficial, focando em estilo em vez de logica e casos de borda.

Quanto tempo deve durar um code review de qualidade?

Pesquisas da SmartBear mostram que revisores comecam a perder eficacia apos revisar mais de 200-400 linhas por hora ou mais de 60-90 minutos de revisao continua. PRs grandes devem ser divididos. Uma sessao eficaz de review raramente dura mais de uma hora.

Que ferramentas de analise estatica vale usar em 2026?

Depende da linguagem. Para C/C++: Coverity, CodeSonar, clang-analyzer. Para Java: SonarQube, SpotBugs, Infer. Para JavaScript/TypeScript: ESLint com plugins de seguranca, semgrep. Para Rust: clippy, cargo audit. Para multiplas linguagens: semgrep e CodeQL (GitHub).

O Que o Review do Ariane 5 Nao Fez

O codigo do sistema de navegacao inercial foi reutilizado do Ariane 4 sem revisao das suposicoes de negocio. A suposicao que quebrou: a velocidade horizontal do foguete nunca excederia 32.767 (o limite de um int16). No Ariane 4, isso era verdade. No Ariane 5, muito mais potente, nao era. Um review que perguntasse 'quais sao as suposicoes de range desse codigo e elas ainda sao validas nesse contexto?' teria encontrado o problema. Um review que verificasse 'o que acontece quando esse valor excede o tipo?' teria encontrado o problema. Mas a maioria dos reviews nao faz essas perguntas. Revisores olham para o codigo e perguntam 'isso parece razoavel?'. Codigo legado que funcionou por anos parece muito razoavel.