Descrever o conceito de Teste de Unidade e fornecer dois exemplos de Testes de Unidade no contexto do Jogo Digital Educativo proposto na questão 2.
(2 pontos)
(2 pontos)
Passo 1
O enunciado pede duas coisas claras: (a) descrever o conceito de “Teste de Unidade” e (b) fornecer dois exemplos de Testes de Unidade no contexto do Jogo Digital Educativo proposto na questão 2. Informações relevantes que temos: o exercício vale
pontos e o jogo é um “Jogo Digital Educativo” (não foram fornecidos detalhes técnicos adicionais do enunciado aqui). Vou assumir partes típicas desse tipo de jogo (por exemplo: função que avalia respostas, sistema de pontuação/XP, cálculo de nível, tempo de resposta, etc.) para construir exemplos concretos e didáticos. Se algum detalhe do jogo for diferente, os exemplos abaixo podem ser adaptados trocando nomes de funções e limites.
Passo 2
O que é um Teste de Unidade — explicação didática e passo a passo:
- Definição simples e direta: um Teste de Unidade verifica o comportamento de uma pequena peça isolada do código (uma “unidade”), normalmente uma função ou método, garantindo que ela faça exatamente o que se espera em situações específicas.
- Por que isso importa? Benefícios rápidos:
- Detecta bugs cedo.
- Permite refatorar código com segurança (se o teste continuar verde, você não quebrou o comportamento).
- Serve como documentação executável do que aquela função deve fazer.
- Características de um bom Teste de Unidade:
- Rápido (deve rodar em milissegundos a segundos).
- Isolado (não depende de rede, banco de dados, interface gráfica — essas dependências são simuladas/mocadas).
- Determinístico (mesma entrada → mesma saída sempre).
- Padrão prático para escrever um teste: AAA (Arrange — preparar, Act — executar, Assert — verificar).
- Arrange: criar entradas e mocar dependências.
- Act: chamar a função/unidade que será testada.
- Assert: comparar o resultado obtido com o esperado e explicar o motivo do esperado.
- Conceitos úteis:
- Mock/Stub: objetos falsos que substituem dependências (por ex., banco) para manter o teste isolado.
- Cobertura (coverage): métrica que indica quanto do código foi exercitado pelos testes (importante, mas não substitui bons testes).
- Exemplo pedagógico do AAA com uma função hipotética: suponha função evaluateAnswer(question, userAnswer) que retorna true/false. AAA seria: (1) Arrange: criar question e userAnswer; (2) Act: chamar evaluateAnswer(…); (3) Assert: esperar true se a resposta estiver correta.
Passo 3
Exemplo de Teste de Unidade 1 — avaliação de resposta e atribuição de pontos (exemplo concreto e explicado passo a passo).
- Contexto do jogo (assumido): existe uma função que avalia se a resposta do aluno está correta e outra que calcula pontos ganhos.
- Função 1 (hipotética): evaluateAnswer(question, userAnswer) → retorna boolean.
- Função 2 (hipotética): awardPoints(isCorrect, timeTaken) → retorna número de pontos inteiros.
- Objetivo do teste 1: verificar que quando a resposta é correta e o tempo está dentro do limite, a função awardPoints retorna os pontos esperados.
- Por que testar isso na prova? Porque a regra de pontuação costuma ser simples e é fácil errar nos limites (por ex., arredondamento, mínimo e máximo).
- Situação de teste (AAA):
- Arrange:
- criar uma questão do tipo múltipla escolha onde a alternativa correta é “B”.
- simular userAnswer = “B”.
- simular timeTaken =
segundos (ex.: limite para bônus é s). - supor regra de pontuação: resposta correta vale
pontos base, bônus de pontos se timeTaken s.
- Act:
- chamar evaluateAnswer(question, userAnswer) → deve retornar true.
- chamar awardPoints(true, 8) → resultado obtido.
- Assert:
- esperar que evaluateAnswer retorne true.
- esperar que awardPoints retorne
(isto é, ).
- Arrange:
- Como escrever o teste (pseudo-código, para entender o formato):
- Arrange:
- question.correct = “B”
- userAnswer = “B”
- timeTaken = 8
- Act:
- isCorrect = evaluateAnswer(question, userAnswer)
- points = awardPoints(isCorrect, timeTaken)
- Assert:
- assert(isCorrect === true)
- assert(points === 120)
- Arrange:
- Observações didáticas:
- Testar também casos de borda: timeTaken =
(deve dar bônus) e timeTaken = (não deve dar bônus). - Se awardPoints depende de uma regra externa (por ex., tabela de pontos carregada do servidor), mocar essa tabela para garantir isolamento.
- Testar também casos de borda: timeTaken =
Passo 4
Exemplo de Teste de Unidade 2 — progressão de nível (boundary/condição limite) com cálculo de XP.
- Contexto do jogo (assumido): jogador tem pontos de experiência (XP) acumulados e existe uma função levelAfterXp(currentXp, gainedXp) que retorna o novo nível do jogador (ou objeto com novo nível e XP restante).
- Tipos de bugs comuns aqui: erros na lógica de transbordo quando a soma de XP ultrapassa exatamente o limite de subida de nível; uso incorreto de < vs
; esquecer de resetar XP residual. - Suposições de regras para o exemplo:
- Nível
→ precisa XP para ir para nível . - Nível
→ precisa XP para ir para nível . - A função aceita (currentLevel, currentXpTowardsNextLevel, gainedXp) e devolve (newLevel, newXpTowardsNextLevel).
- Nível
- Objetivo do teste 2: garantir que quando o jogador tem exatamente o XP necessário após ganhar novos pontos, o nível aumenta e o XP restante é zero.
- Situação de teste (AAA):
- Arrange:
- currentLevel =
- currentXpTowardsNextLevel =
- gainedXp =
- regra: para passar do nível
para precisa XP.
- currentLevel =
- Act:
- chamar levelAfterXp(1, 40, 60)
- Assert:
- esperar newLevel ===
- esperar newXpTowardsNextLevel ===
(pois , exatamente o limite)
- esperar newLevel ===
- Arrange:
- Explicação passo a passo do cálculo:
- Soma de XP:
. - Limite do nível
: . - Como soma
, sobe um nível: newLevel = . - XP residual após subir:
.
- Soma de XP:
- Casos adicionais que normalmente testamos junto (sugestões para a prova):
- ganho que excede o limite por mais de um nível (ex.: gainedXp =
pode subir múltiplos níveis). - ganho zero (gainedXp =
) — não muda nível. - valores negativos devem ser proibidos (input validation).
- ganho que excede o limite por mais de um nível (ex.: gainedXp =
- Observação sobre implementação do teste: mocar consulta à tabela de XP necessária por nível (se existir) para não depender de arquivo externo.
Passo 5
Como isolar dependências e usar mocks nos exemplos acima (explicando o porquê e como na prática)
- Por que isolar? Porque queremos testar só a lógica da unidade (p.ex., awardPoints), não se o servidor respondeu ou se o banco está online.
- No Exemplo 1:
- se awardPoints pega multiplicadores de uma API (promoção), criar um mock dessa API com retorno conhecido.
- assim o teste sempre será determinístico.
- No Exemplo 2:
- se levelAfterXp consulta uma tabela externa para saber quantos XP cada nível exige, substituir essa tabela por uma versão em memória no teste.
- Ferramentas comuns (nomes só para referência): Jest (JS), pytest + unittest.mock (Python), JUnit + Mockito (Java). Conceito é o mesmo: substituir dependências reais por objetos controlados.
Passo 6
Boas práticas e dicas rápidas para a prova (o que escrever na resposta curta)
- Ao descrever o conceito: seja conciso — defina unidade, objetivo e características (rápido, isolado, determinístico).
- Ao dar exemplos: explique claramente o Arrange/Act/Assert e mostre os inputs e a saída esperada — isso prova que você entendeu e sabe aplicar.
- Sempre cite casos de borda (limite) e a necessidade de mockar dependências externas.
- Nomeie os testes de forma descritiva, por ex.: test_awardPoints_correctAnswer_withBonus_returns120.
Passo 7
Recapitulando numa linguagem direta e encorajadora (um empurrão final)
- Você pode responder na prova assim: primeira parte — definição curta e benefícios; segunda parte — dois testes descritos com entradas, execução e asserções (como fiz nos exemplos). Se ficar nervoso, copie a estrutura AAA e preencha com os valores que o enunciado do jogo der — isso sempre ganha pontos porque mostra que você sabe testar a unidade corretamente. Vai dar certo!
Resposta
Um Teste de Unidade é um teste automatizado que verifica o comportamento de uma pequena peça isolada do código (normalmente uma função ou método), garantindo que ela produza a saída esperada para entradas específicas; essas verificações devem ser rápidas, determinísticas e isoladas de dependências externas (por exemplo, usando mocks).
Exemplo 1: Teste de avaliação de resposta e pontuação — Arrange: question.correct = “B”, userAnswer = “B”, timeTaken = ; Act: isCorrect = evaluateAnswer(question, userAnswer), points = awardPoints(isCorrect, timeTaken); Assert: isCorrect === true e points ===
(supondo
pontos base +
de bônus).
Exemplo 2: Teste de progressão de nível na fronteira — Arrange: currentLevel = , currentXpTowardsNextLevel =
, gainedXp =
; Act: (newLevel, newXp) = levelAfterXp(1, 40, 60); Assert: newLevel ===
e newXp ===
(pois
, que é o limite para subir do nível
para o
).
Exemplo 1: Teste de avaliação de resposta e pontuação — Arrange: question.correct = “B”, userAnswer = “B”, timeTaken =
Exemplo 2: Teste de progressão de nível na fronteira — Arrange: currentLevel =