Fundamentos de qualidade: requisitos, rastreabilidade e critérios de aceitação
Qualidade de software é a capacidade do sistema atender às necessidades do usuário e às regras do negócio com confiabilidade, segurança, desempenho adequado e facilidade de manutenção. Em concursos, é comum a cobrança de conceitos que conectam requisitos, testes e controle de mudanças.
Requisitos: o que o sistema deve fazer (e sob quais condições)
Um requisito descreve uma necessidade. Pode ser funcional (comportamento) ou não funcional (qualidade, restrições). Para evitar ambiguidade, requisitos devem ser claros, testáveis e verificáveis.
- Funcional: “Permitir transferências via PIX para chaves cadastradas.”
- Não funcional: “Confirmar a transferência em até 2 segundos em 95% das requisições.”
- Regra de negócio: “Transferências acima de R$ 10.000 exigem autenticação adicional.”
Critérios de aceitação: como saber se o requisito foi cumprido
Critérios de aceitação são condições objetivas para considerar uma funcionalidade pronta. Eles orientam desenvolvimento e testes e reduzem retrabalho. Um formato comum é o BDD (Given/When/Then).
Critério de aceitação (exemplo - PIX com limite diário)Dado que o cliente possui limite diário de PIX de R$ 2.000,00 já utilizado em R$ 1.800,00,Quando ele tentar enviar um PIX de R$ 300,00,Então o sistema deve bloquear a transação e exibir mensagem de limite excedido.Note que o critério é mensurável: há valores, condição e resultado esperado.
Rastreabilidade: ligar requisito → implementação → teste
Rastreabilidade é a capacidade de acompanhar um requisito desde sua origem até a entrega: quais commits implementaram, quais testes cobrem e quais evidências validam. Ajuda a responder perguntas como: “Se eu mudar esta regra, o que pode quebrar?”
Continue em nosso aplicativo
Você poderá ouvir o audiobook com a tela desligada, ganhar gratuitamente o certificado deste curso e ainda ter acesso a outros 5.000 cursos online gratuitos.
ou continue lendo abaixo...Baixar o aplicativo
- Requisito (ID: RF-PIX-012) →
- História/Tarefa (JIRA/board) →
- Commits (mensagens referenciando o ID) →
- Casos de teste (CT-PIX-045) →
- Execução (pipeline/relatório) →
- Release (tag/versão)
Em prova, rastreabilidade costuma aparecer como mecanismo de controle de mudanças e garantia de cobertura de requisitos.
Dívida técnica: custo futuro por atalhos no presente
Dívida técnica é o “passivo” criado quando se escolhe uma solução rápida (ou incompleta) que aumenta o custo de manutenção e evolução. Não é sempre “erro”; pode ser uma decisão consciente, mas precisa ser gerenciada.
- Exemplos: duplicação de código, ausência de testes automatizados, acoplamento excessivo, documentação desatualizada, regras de negócio espalhadas.
- Efeitos: mais bugs, releases mais lentos, dificuldade de refatorar, maior risco em mudanças.
- Gestão: registrar, priorizar pagamento (refatoração), criar limites (Definition of Done), monitorar indicadores (falhas recorrentes, tempo de correção).
Testes de software: tipos, objetivos e quando usar
Testes verificam se o software se comporta como esperado e ajudam a detectar falhas cedo. A classificação mais cobrada envolve nível (unitário, integração, sistema) e finalidade (regressão).
Teste unitário
Valida a menor unidade testável (função/método/classe) de forma isolada. Geralmente usa dublês (mocks/stubs) para dependências externas.
- Objetivo: garantir regras locais e cálculos corretos.
- Vantagens: rápido, barato, localiza falhas com precisão.
- Limitação: não garante que integrações funcionem.
Exemplo conceitual de caso de teste unitário (regra de limite)Cenário: bloquear PIX acima do limite restanteEntrada: limiteRestante=200, valor=300Saída esperada: erro LimiteExcedidoTeste de integração
Valida a interação entre componentes: módulo + banco, serviço + fila, API + autenticação, etc. Pode ser com dependências reais (ambiente de teste) ou simuladas.
- Objetivo: detectar falhas de contrato, serialização, configuração, credenciais, transações.
- Exemplo de falha típica: campo obrigatório no banco não é preenchido pela aplicação.
Exemplo conceitual de teste de integraçãoCenário: registrar transação PIX no bancoQuando a API recebe uma transferência válidaEntão deve persistir registro com status=CONFIRMADA e idTransacao não nuloTeste de sistema (end-to-end)
Valida o sistema completo do ponto de vista do usuário ou de um fluxo de negócio, passando por múltiplos componentes.
- Objetivo: garantir que o fluxo funciona “de ponta a ponta”.
- Exemplo: login → autenticação adicional → efetuar PIX → consultar comprovante.
- Custo: mais lento e mais frágil (depende de muitos elementos).
Teste de regressão
Regressão é a reexecução de testes (ou um subconjunto) para garantir que mudanças não quebraram funcionalidades existentes. Pode incluir testes unitários, integração e sistema.
- Quando: após correções, refatorações, atualizações de dependências, mudanças de regra.
- Boa prática: automatizar o máximo possível e rodar em pipeline.
Cobertura de testes e automação (nível conceitual)
O que é cobertura
Cobertura mede o quanto do código (ou requisitos) é exercitado pelos testes. As métricas mais comuns:
- Cobertura de linhas: percentual de linhas executadas.
- Cobertura de ramos/decisões: percentual de caminhos em condicionais (if/else, switch) exercitados.
- Cobertura de requisitos: percentual de requisitos com testes associados (rastreabilidade).
Importante: alta cobertura não garante ausência de bugs. Um teste pode executar uma linha sem validar o resultado correto (asserções fracas).
Automação de testes: por que e como pensar
Automatizar testes significa codificar a execução e verificação para rodar repetidamente com baixo custo. Em contexto de entrega contínua, automação reduz risco e acelera feedback.
- Automatizar primeiro: testes unitários e parte dos de integração (rápidos e estáveis).
- Automatizar com cuidado: testes end-to-end (mais caros e instáveis), focando fluxos críticos.
- Gatilhos comuns: a cada commit/pull request, antes de merge, antes de release (tag).
Controle de versão com Git: branch, merge, conflitos e tags
Git registra o histórico de mudanças no código, permitindo colaboração, auditoria e reversão. Para concursos, é essencial entender o vocabulário e o fluxo básico.
Branch: linhas de trabalho paralelas
Branch é uma ramificação do histórico para desenvolver uma funcionalidade/correção sem afetar a linha principal.
- main/master: linha principal estável.
- feature/...: desenvolvimento de funcionalidade.
- hotfix/...: correção urgente.
Passo a passo (conceitual) de trabalho com branch1) Atualizar a main local (git pull)2) Criar branch de feature (git checkout -b feature/limite-pix)3) Fazer commits pequenos e descritivos4) Abrir pull request para revisão5) Após aprovação e testes, fazer merge na mainMerge: unir mudanças
Merge integra as alterações de uma branch em outra. Em equipes, o merge costuma ocorrer via pull request para permitir revisão e execução de testes automatizados.
- Merge sem conflito: Git consegue combinar automaticamente.
- Merge com conflito: duas alterações incompatíveis na mesma região do arquivo.
Conflitos: por que acontecem e como resolver
Conflitos ocorrem quando duas branches modificam as mesmas linhas (ou trechos próximos) e o Git não sabe qual versão manter.
Exemplo de conflito (marcadores do Git)<<<<<<< HEADlimiteDiario = 2000=======limiteDiario = 2500>>>>>>> feature/ajuste-limitePasso a passo para resolver conflito (prático)1) Identificar arquivos em conflito (git status)2) Abrir o arquivo e decidir a versão correta (ou combinar as duas)3) Remover marcadores <<<<<<<, =======, >>>>>>>4) Rodar testes (unitários/integração) para validar5) Marcar como resolvido (git add arquivo)6) Finalizar o merge (git commit) ou continuar o rebase, se for o casoTags: marcar versões
Tag é um marcador no histórico, normalmente usado para identificar releases (ex.: v1.3.0). Ajuda a rastrear qual código foi para produção e facilita rollback.
- Uso típico: após aprovação em testes e merge na main, cria-se uma tag para empacotar a versão.
- Rastreabilidade: requisito/teste → commit → tag (versão entregue).
Práticas de revisão: pull request, checklist e leitura de diffs
Revisão de código reduz defeitos, melhora legibilidade e dissemina padrões. Em ambientes regulados, também contribui para governança e auditoria.
O que revisar em um pull request
- Corretude: atende ao requisito e aos critérios de aceitação?
- Testes: há testes novos/ajustados? Cobrem casos de borda?
- Legibilidade: nomes, complexidade, duplicação.
- Risco: mudança em área sensível? Impacto em performance?
- Segurança: validações, tratamento de erros, dados sensíveis em logs.
Como ler um diff (exemplo)
diff --git a/limite.py b/limite.py@@ -10,7 +10,9 @@ def pode_enviar_pix(limite_restante, valor):- return valor <= limite_restante+ if valor <= 0:+ raise ValueError("valor invalido")+ return valor <= limite_restanteInterpretação do diff:
- Linhas com - foram removidas.
- Linhas com + foram adicionadas.
- O trecho @@ indica a região do arquivo alterada.
Perguntas de revisão para esse diff:
- Existe critério de aceitação para valor zero/negativo?
- Há teste unitário cobrindo a exceção?
- A exceção é tratada em camadas superiores (API) para retornar erro adequado?
Exemplos de casos de teste (com foco em critérios de aceitação)
Modelo simples de caso de teste
- ID: CT-PIX-045
- Objetivo: validar bloqueio por limite excedido
- Pré-condições: cliente autenticado; limite diário configurado
- Dados: limiteRestante=200; valor=300
- Passos: solicitar transferência PIX de R$ 300
- Resultado esperado: transação negada; mensagem “limite excedido”; nenhum registro de confirmação
Casos de borda (edge cases) úteis em prova
- Valor exatamente no limite: valor=200 deve permitir.
- Valor mínimo: valor=0 ou negativo deve rejeitar.
- Precisão monetária: valor com centavos (ex.: 199,99) e arredondamento.
- Concorrência lógica: duas solicitações quase simultâneas consumindo o mesmo limite (pode exigir teste de integração/sistema dependendo da implementação).
Exercícios: identificar o tipo de teste adequado para cada falha
Exercício 1
Falha: a função de cálculo do limite restante retorna valor negativo quando o valor do PIX é maior que o limite.
- Pergunta: qual tipo de teste detecta mais cedo?
- Opções: unitário, integração, sistema, regressão
Exercício 2
Falha: ao salvar a transação, o sistema lança erro de “campo obrigatório ausente” no banco de dados.
- Pergunta: qual tipo de teste é mais indicado?
- Opções: unitário, integração, sistema, regressão
Exercício 3
Falha: o usuário consegue completar o fluxo de PIX, mas o comprovante não aparece na tela de extrato.
- Pergunta: qual tipo de teste cobre melhor o fluxo?
- Opções: unitário, integração, sistema, regressão
Exercício 4
Falha: após uma mudança em validação de valor, funcionalidades antigas de TED começaram a falhar.
- Pergunta: qual categoria de teste é essencial executar?
- Opções: unitário, integração, sistema, regressão
Gabarito comentado (para autoavaliação)
- Exercício 1: teste unitário (regra local de cálculo/validação).
- Exercício 2: teste de integração (aplicação + banco/esquema).
- Exercício 3: teste de sistema (fluxo ponta a ponta envolvendo múltiplos componentes/telas).
- Exercício 4: teste de regressão (garantir que mudanças não quebraram funcionalidades existentes).