Cobertura de Testes
Entendendo Cobertura de Testes
Cobertura de testes é a porcentagem do código-fonte que é exercida por testes automatizados. Uma cobertura robusta significa que mudanças futuras serão detectadas rapidamente se quebrarem as funcionalidades existentes.
Por que Importa?
- Reduz regressões em 70-90% (Amann & Jürgens, 2020)
- Aumenta confiança para refatoração
- Documenta comportamento esperado do código
- Facilita manutenção de código legado
Exemplo Prático
# Código sem cobertura
def calcular_desconto(preco, cliente):
if cliente['tipo'] == 'vip':
return preco * 0.8
return preco * 0.9
# Testes unitários que cobrem ambos os cenários
def test_aplica_desconto_vip():
assert calcular_desconto(100, {'tipo': 'vip'}) == 80
def test_aplica_desconto_comum():
assert calcular_desconto(100, {'tipo': 'comum'}) == 90
Iteração de SDLC sem Cobertura de Testes
- Software Estável:
- Ainda não há alterações instáveis (cinza).
- Processo de Desenvolvimento:
- Desenvolvedor:
- Adiciona um novo bloco de código ainda sem testes (vermelho).
- NÃO escreve testes para o novo código.
- Rotina de Teste:
- Testes manuais para verificar o código.
- Desenvolvedor corrige o código para que os testes sejam aprovados.
- Desenvolvedor:
- Processo de Teste:
- Código novo é testado e bugs são corrigidos.
- Código antigo é testado e bugs são corrigidos.
- Parte dos bugs é corrigida, mas não todos, pois não há rastreabilidade.
- Software Após Iteração:
- Software com blocos instáveis (laranja).
- Recebe um novo bloco de código (vermelho).
- O processo se repete.
Iteração de SDLC com Cobertura de Testes
- Software Estável:
- Ainda não há alterações instáveis (cinza).
- Alguns blocos do código estão cobertos por testes (azul).
- Processo de Desenvolvimento:
- Desenvolvedor:
- Adiciona um novo bloco de código ainda sem testes (vermelho).
- Escreve testes para o novo código.
- Rotina de Teste:
- Executa os testes.
- Os testes falham e avisam o desenvolvedor (verde).
- Desenvolvedor corrige o código para que os testes sejam aprovados.
- Desenvolvedor:
- Processo de Teste:
- Execução coberta de testes (azul).
- Código novo é testado e bugs são corrigidos.
- Código antigo é testado e bugs são corrigidos.
- Testes são escritos para os bugs descobertos pelos novos testes (verde).
- Software Após Iteração:
- Software com cobertura de testes estável (azul).
- Recebe um novo bloco de código (vermelho).
- Novos testes foram escritos para o novo código (verde).
- O processo se repete.
Armadilha: Cobertura vs. Qualidade
⚠️ Alta cobertura ≠ Testes de qualidade
Um teste que apenas verifica se a função executa sem erros é uma "falsa cobertura".
# ❌ Teste que cobre a linha, mas não valida o resultado
def test_executa_calcular_desconto():
calcular_desconto(100, {'tipo': 'vip'})
# Sem validação do resultado!
# ✅ Teste de qualidade que valida comportamento
def test_aplica_desconto_correto_para_vip():
assert calcular_desconto(100, {'tipo': 'vip'}) == 80
# Valida o resultado esperado
Priorize a qualidade sobre a quantidade de linhas cobertas. Um teste ruim é pior do que nenhum teste.
Implementando Cobertura de Testes
Fase 1: Diagnóstico
- Medir cobertura atual do seu projeto com ferramentas (Jest, Istanbul, Codecov)
- Identificar áreas críticas com baixa cobertura
- Documentar baseline atual
Fase 2: Priorização
- Cobrir código crítico primeiro (regras de negócio, fluxos financeiros)
- Focar no código frequentemente alterado
- Ignorar getters e setters triviais
Fase 3: Iteração Gradual
- Aumentar de 5 a 10% de cobertura por ciclo de desenvolvimento
- Exigir testes para todo novo código via pull requests
- Revisar a qualidade dos testes, não apenas a porcentagem de cobertura
Fase 4: Manutenção
- Configurar CI/CD para falhar caso a cobertura caia
- Revisar os relatórios de cobertura regularmente
- Educar a equipe sobre falsa cobertura
Observações Importantes:
- Execução completa regular: Mesmo com alta cobertura, execute toda a suíte periodicamente
- Mudanças não-código: Alterações em configuração, dados ou metadados podem n ão ser detectadas
- Cobertura ≠ Qualidade: Código executado 5 vezes mais propenso a erros se não testado adequadamente
Mapa Mental
- 🎯 Cobertura de Testes
- 📊 Entendimento - Por que Importa?
- Reduz regressões 70%
- Facilita refatoração
- Documenta comportamento
- 🔄 Comparação SDLC
- 🔴 SEM Cobertura
- Testes manuais
- Bugs não rastreados
- Software instável
- Débito técnico acumulado
- 🟢 COM Cobertura
- Testes automatizados
- Rastreabilidade completa
- Software estável
- Cobertura gradual
- Menos débito técnico
- 🔴 SEM Cobertura
- ⚠️ Armadilhas - Falsa Cobertura
- Priorize qualidade sobre quantidade
- 📋 Implementação
- 🔍 Diagnóstico
- 🎯 Priorização
- 🔄 Iteração
- ⚙️ Manutenção
- 📊 Entendimento - Por que Importa?
Referências
- Artigos:
- AMANN, Sven; JÜRGENS, Elmar. Change-Driven Testing. In: THE FUTURE OF SOFTWARE QUALITY ASSURANCE. 2020. p. 1-14.
- https://doi.org/10.1007/978-3-030-29509-7_1
- Referência na forma de diagramar a presença de erros e cobertura de testes em um sistema; Foi adaptada em uma nova imagem para demonstrar a diferença entre o cenário de desenvolvimento com e sem cobertura de testes.
- AMANN, Sven; JÜRGENS, Elmar. Change-Driven Testing. In: THE FUTURE OF SOFTWARE QUALITY ASSURANCE. 2020. p. 1-14.