8 min leitura • Guide 605 of 877
Melhores Práticas de Estratégia de Teste
Uma estratégia de teste sólida captura bugs cedo, permite refatoração confiante e previne regressões de chegar em produção. O GitScrum ajuda equipes a rastrear tarefas de teste junto com trabalho de desenvolvimento, garantindo que qualidade seja construída no processo, não anexada no final.
Tipos de Teste
| Tipo | Velocidade | Escopo | Quantidade |
|---|---|---|---|
| Unitário | Rápido | Função/classe única | Muitos |
| Integração | Médio | Conexões de componentes | Alguns |
| E2E | Lento | Fluxos completos de usuário | Poucos |
| Contrato | Rápido | Fronteiras de API | Conforme necessário |
| Performance | Lento | Carga/stress | Caminhos chave |
Pirâmide de Testes
ESTRUTURA DA PIRÂMIDE:
┌─────────────────────────────────────────────────────────────┐
│ │
│ ┌─────────┐ │
│ │ E2E │ Poucos, lentos, críticos │
│ ┌──┴─────────┴──┐ │
│ │ Integração │ Alguns, moderados │
│ ┌──┴───────────────┴──┐ │
│ │ Unitário │ Muitos, rápidos │
│ └─────────────────────┘ │
│ │
│ Bom balanço: │
│ ├── 70% testes unitários │
│ ├── 20% testes de integração │
│ └── 10% testes E2E │
│ │
│ ─────────────────────────────────────────────────────────── │
│ │
│ ANTI-PADRÃO - CONE DE SORVETE: │
│ ┌─────────────────────┐ │
│ │ Teste manual │ ← Muito teste manual │
│ └───────┬─────────────┘ │
│ ┌────┴────┐ │
│ │ E2E │ ← Muitos E2E │
│ └────┬────┘ │
│ ┌─────┴─────┐ │
│ │Integração │ │
│ └─────┬─────┘ │
│ ┌───┴───┐ │
│ │ Unit │ ← Poucos unitários │
│ └───────┘ │
│ │
│ Problemas: CI lento, testes flaky, feedback demorado │
└─────────────────────────────────────────────────────────────┘
Teste Unitário
ESTRATÉGIA DE TESTE UNITÁRIO:
┌─────────────────────────────────────────────────────────────┐
│ │
│ O QUE TESTAR (Alta prioridade): │
│ ├── Lógica de negócio │
│ ├── Cálculos complexos │
│ ├── Transições de estado │
│ ├── Edge cases │
│ ├── Tratamento de erros │
│ └── Funções utilitárias │
│ │
│ O QUE TESTAR (Baixa prioridade): │
│ ├── Getters/setters simples │
│ ├── Boilerplate de framework │
│ └── Wrappers de bibliotecas terceiras │
│ │
│ ─────────────────────────────────────────────────────────── │
│ │
│ PRINCÍPIOS FIRST: │
│ ├── Fast: Milissegundos, não segundos │
│ ├── Isolated: Sem dependências externas │
│ ├── Repeatable: Mesmo resultado toda vez │
│ ├── Self-validating: Passa/falha claro │
│ └── Timely: Escrito junto ou antes do código │
│ │
│ ─────────────────────────────────────────────────────────── │
│ │
│ PADRÃO AAA: │
│ ├── Arrange: Configure dados de teste │
│ ├── Act: Execute a função │
│ └── Assert: Verifique o resultado │
│ │
│ EXEMPLO: │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ describe('calcularDesconto', () => { ││
│ │ it('aplica 10% desconto para pedidos > R$100', () =>││
│ │ // Arrange ││
│ │ const pedido = { total: 150 }; ││
│ │ ││
│ │ // Act ││
│ │ const resultado = calcularDesconto(pedido); ││
│ │ ││
│ │ // Assert ││
│ │ expect(resultado).toBe(15); ││
│ │ }); ││
│ │ ││
│ │ it('retorna 0 para pedidos <= R$100', () => { ││
│ │ const pedido = { total: 100 }; ││
│ │ expect(calcularDesconto(pedido)).toBe(0); ││
│ │ }); ││
│ │ }); ││
│ └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘
Teste de Integração
ESTRATÉGIA DE INTEGRAÇÃO:
┌─────────────────────────────────────────────────────────────┐
│ │
│ O QUE TESTAR: │
│ ├── Endpoints de API │
│ ├── Interações com banco de dados │
│ ├── Integrações com serviços externos │
│ ├── Comunicação entre componentes │
│ └── Middleware e pipelines │
│ │
│ CONFIGURAÇÃO: │
│ ├── Banco de dados de teste (in-memory ou container) │
│ ├── Mock de serviços externos │
│ ├── Dados de teste realistas │
│ └── Limpeza entre testes │
│ │
│ EXEMPLO DE TESTE DE API: │
│ ┌─────────────────────────────────────────────────────────┐│
│ │ describe('POST /pedidos', () => { ││
│ │ it('cria pedido e salva no banco', async () => { ││
│ │ // Arrange ││
│ │ const items = [{ produtoId: 1, qtd: 2 }]; ││
│ │ ││
│ │ // Act ││
│ │ const response = await request(app) ││
│ │ .post('/pedidos') ││
│ │ .send({ items }); ││
│ │ ││
│ │ // Assert ││
│ │ expect(response.status).toBe(201); ││
│ │ const pedido = await Pedido.findById( ││
│ │ response.body.id ││
│ │ ); ││
│ │ expect(pedido.items).toHaveLength(1); ││
│ │ }); ││
│ │ }); ││
│ └─────────────────────────────────────────────────────────┘│
└─────────────────────────────────────────────────────────────┘
Teste E2E
ESTRATÉGIA E2E:
┌─────────────────────────────────────────────────────────────┐
│ │
│ QUANDO USAR E2E: │
│ ├── Jornadas críticas de usuário │
│ ├── Fluxos de receita (checkout, pagamento) │
│ ├── Autenticação e autorização │
│ └── Integrações críticas de negócio │
│ │
│ BOAS PRÁTICAS E2E: │
│ ├── Mantenha poucos (< 50 para maioria dos apps) │
│ ├── Foque em happy paths │
│ ├── Use seletores estáveis (data-testid) │
│ ├── Implemente retry e wait apropriados │
│ └── Rode em ambiente isolado │
│ │
│ ─────────────────────────────────────────────────────────── │
│ │
│ LIDANDO COM FLAKINESS: │
│ │
│ Causas comuns: │
│ ├── Timing issues │
│ ├── Dados compartilhados entre testes │
│ ├── Dependências externas instáveis │
│ └── Seletores frágeis │
│ │
│ Soluções: │
│ ├── Wait explícito por elementos │
│ ├── Isolamento de dados por teste │
│ ├── Mock de serviços não críticos │
│ └── Retry automático (com moderação) │
└─────────────────────────────────────────────────────────────┘
Cobertura de Código
ESTRATÉGIA DE COBERTURA:
┌─────────────────────────────────────────────────────────────┐
│ │
│ METAS REALISTAS: │
│ │
│ ├── Lógica de negócio: 90%+ │
│ ├── Utilitários/helpers: 80%+ │
│ ├── Código geral: 70%+ │
│ └── Código de UI: Varia (foque em lógica) │
│ │
│ O QUE A COBERTURA NÃO DIZ: │
│ │
│ ✗ Se os testes são bons │
│ ✗ Se edge cases estão cobertos │
│ ✗ Se o código funciona corretamente │
│ │
│ Cobertura alta + testes ruins = falsa confiança │
│ │
│ ─────────────────────────────────────────────────────────── │
│ │
│ FOQUE EM: │
│ │
│ ✓ Testar comportamento, não implementação │
│ ✓ Cobrir caminhos críticos primeiro │
│ ✓ Adicionar testes quando bugs aparecem │
│ ✓ Qualidade sobre quantidade │
│ │
│ REGRA: │
│ "Cobertura é um limite inferior, não uma meta" │
│ 60% significativo > 90% trivial │
└─────────────────────────────────────────────────────────────┘
Pipeline de Testes
TESTES NO CI/CD:
┌─────────────────────────────────────────────────────────────┐
│ │
│ COMMIT/PUSH: │
│ ├── Lint │
│ ├── Testes unitários (< 5 min) │
│ └── Build check │
│ │
│ PULL REQUEST: │
│ ├── Testes unitários │
│ ├── Testes de integração (< 15 min) │
│ ├── Cobertura check │
│ └── Review gates │
│ │
│ MERGE TO MAIN: │
│ ├── Suite completa │
│ ├── Testes E2E │
│ └── Deploy para staging │
│ │
│ PRE-PRODUCTION: │
│ ├── Smoke tests │
│ ├── Testes de performance │
│ └── Verificação de segurança │
│ │
│ ─────────────────────────────────────────────────────────── │
│ │
│ PARALELIZAÇÃO: │
│ • Divida testes em shards │
│ • Rode independentes em paralelo │
│ • Cache de dependências │
│ • Selecione apenas testes afetados quando possível │
└─────────────────────────────────────────────────────────────┘