Teste de mesa e rastreamento de variáveis
Aprenda a projetar tabelas de teste de mesa, registrar mudanças de estado e rastrear decisões, laços, funções e resultados sem pular etapas.

Uma tabela de rastreamento transforma execução em estado observável
Um teste de mesa simula um algoritmo com uma entrada concreta. O rastreamento de variáveis é o registro disciplinado dessa simulação: em momentos definidos, você anota quais instruções foram executadas, quais condições foram avaliadas e qual valor cada variável possui.
O objetivo não é copiar o algoritmo inteiro para uma tabela. É produzir uma sequência de estados que responda três perguntas:
- onde a execução está?
- qual decisão acabou de ser tomada?
- o que mudou em relação ao estado anterior?
Se o resultado estiver errado, a tabela permite procurar a primeira linha em que o estado obtido deixa de corresponder ao esperado. Ela aprofunda o procedimento apresentado em como testar um algoritmo manualmente e torna o diagnóstico reproduzível.
Defina o ponto de captura antes de preencher a tabela
Uma variável pode ter valores diferentes antes e depois da mesma instrução. Por isso, toda tabela precisa declarar quando cada linha é registrada.
Considere:
total = total + valor
Se total vale 7 e valor vale 4, o estado anterior à instrução contém total = 7; o estado posterior contém total = 11. Os dois registros são corretos, mas não podem ser misturados na mesma convenção.
Para laços, uma escolha prática é criar:
- uma linha de inicialização;
- uma linha após cada execução completa do corpo;
- uma linha final para a condição de saída ou para o resultado.
Quando o objetivo é investigar uma condição, registre também o estado imediatamente antes da decisão. Escreva a convenção acima da tabela: “valores após o corpo”, “valores antes da condição” ou outra descrição inequívoca.
Escolha colunas que expliquem o comportamento
Comece pela pergunta que o rastro precisa responder. Depois escolha as colunas.
Uma tabela costuma combinar quatro tipos de informação:
| Tipo | O que registrar | Exemplo |
|---|---|---|
| localização | etapa, iteração ou linha lógica | iteração 2 |
| entrada corrente | valor que está sendo processado | nota = 9 |
| controle | condição e caminho selecionado | nota >= 5 → verdadeiro |
| estado acumulado | valores que sobrevivem entre passos | soma = 16, quantidade = 2 |
Não inclua todas as variáveis por hábito. Uma constante que nunca muda pode aparecer no cabeçalho ou numa observação. Uma variável temporária irrelevante para a pergunta pode ficar de fora. Em contrapartida, não omita uma condição que decide se o estado será atualizado.
Use — para “ainda não existe” ou “não se aplica”. Não use 0 no lugar de ausência: zero é um valor real e pode alterar a interpretação.
Construa o rastro a partir de um caso pequeno
Vamos calcular a média somente das notas maiores ou iguais a 5:
notas = [7, 4, 9, 2]
soma = 0
quantidade = 0
para indice de 0 até tamanho(notas) - 1
nota = notas[indice]
se nota >= 5
soma = soma + nota
quantidade = quantidade + 1
se quantidade > 0
media = soma / quantidade
senão
media = ausente
Antes de simular, calcule o esperado por um caminho independente. As notas selecionadas são 7 e 9; portanto, a soma deve ser 16, a quantidade deve ser 2 e a média deve ser 8.
O caso é pequeno, mas contém coleção, índice, variável corrente, decisão, acumulador, contador e uma proteção contra divisão por zero.
Preencha primeiro o estado inicial
Nossa convenção será: uma linha após a inicialização e uma linha após cada execução completa do corpo do laço.
Antes da primeira iteração:
| Momento | Índice | Nota | nota >= 5 | Soma | Quantidade |
|---|---|---|---|---|---|
| inicialização | — | — | — | 0 | 0 |
indice e nota ainda não receberam valores do laço. Por isso aparecem como ausência, não como zero. Já soma e quantidade foram inicializadas explicitamente com zero.
Registrar esse estado evita atribuir ao primeiro item valores que existiam antes de ele ser lido.
Atualize uma linha de cada vez
Na primeira iteração, indice = 0 e nota = 7. A condição é verdadeira, então os dois estados acumulados mudam:
| Momento | Índice | Nota | nota >= 5 | Soma | Quantidade |
|---|---|---|---|---|---|
| inicialização | — | — | — | 0 | 0 |
| após iteração 0 | 0 | 7 | verdadeiro | 7 | 1 |
Na segunda, nota = 4. A condição é falsa. O algoritmo visita o item, mas não executa as duas atribuições internas. Copie os valores mantidos:
| Momento | Índice | Nota | nota >= 5 | Soma | Quantidade |
|---|---|---|---|---|---|
| após iteração 1 | 1 | 4 | falso | 7 | 1 |
“Não mudou” também é informação. Deixar a célula vazia poderia significar ausência, esquecimento ou permanência. Repetir 7 e 1 torna o estado completo.
Complete as duas iterações restantes:
| Momento | Índice | Nota | nota >= 5 | Soma | Quantidade |
|---|---|---|---|---|---|
| inicialização | — | — | — | 0 | 0 |
| após iteração 0 | 0 | 7 | verdadeiro | 7 | 1 |
| após iteração 1 | 1 | 4 | falso | 7 | 1 |
| após iteração 2 | 2 | 9 | verdadeiro | 16 | 2 |
| após iteração 3 | 3 | 2 | falso | 16 | 2 |
Registre o resultado fora do laço
Depois do percurso, quantidade > 0 é verdadeira. A última divisão produz:
media = 16 / 2
media = 8
Você pode adicionar uma linha final:
| Momento | Soma | Quantidade | quantidade > 0 | Média |
|---|---|---|---|---|
| após o laço | 16 | 2 | verdadeiro | 8 |
Separar essa linha é importante: a média não é recalculada em cada iteração. Colocá-la nas linhas do laço sugeriria uma ordem de execução que o algoritmo não possui.
Agora compare três resultados independentes:
- previsão anterior à simulação:
8; - estado final rastreado:
8; - saída produzida pelo algoritmo implementado: deve ser
8.
A concordância deste caso não prova que o algoritmo funciona para todas as entradas. Ela confirma somente o percurso rastreado.
Use a primeira divergência para encontrar uma atualização mal posicionada
Suponha que quantidade = quantidade + 1 tenha sido recuada por engano e fique fora do bloco condicional:
para cada nota
se nota >= 5
soma = soma + nota
quantidade = quantidade + 1
O rastro observado passa a ser:
| Iteração | Nota | Condição | Soma esperada/observada | Quantidade esperada | Quantidade observada |
|---|---|---|---|---|---|
| 0 | 7 | verdadeiro | 7 / 7 | 1 | 1 |
| 1 | 4 | falso | 7 / 7 | 1 | 2 |
| 2 | 9 | verdadeiro | 16 / 16 | 2 | 3 |
| 3 | 2 | falso | 16 / 16 | 2 | 4 |
O sintoma final é média 4, mas a primeira divergência acontece na iteração 1, quando uma nota rejeitada aumenta a quantidade. A tabela liga a falha à posição da atualização.
Esse é o uso diagnóstico: não examine apenas a última linha. Compare esperado e observado de cima para baixo e pare na primeira diferença, como detalhado em como identificar erros em um algoritmo.
Em um while, mostre a condição final falsa
Um for frequentemente deixa inicialização, teste e avanço implícitos. No while, essas etapas merecem colunas próprias:
indice = 0
total = 0
enquanto indice < 3
total = total + indice
indice = indice + 1
Use uma linha por avaliação da condição:
| Avaliação | Índice antes do corpo | indice < 3 | Total após o corpo | Índice após o corpo |
|---|---|---|---|---|
| 1 | 0 | verdadeiro | 0 | 1 |
| 2 | 1 | verdadeiro | 1 | 2 |
| 3 | 2 | verdadeiro | 3 | 3 |
| 4 | 3 | falso | — | — |
A última linha explica por que o laço terminou. O corpo não executou nessa avaliação, então os campos “após o corpo” não se aplicam. Essa convenção ajuda a diagnosticar condições de parada e laços infinitos.
Em laços aninhados, uma linha representa o corpo mais interno
Se uma matriz é percorrida por linha e coluna, registre as duas coordenadas. Uma linha da tabela deve corresponder a uma visita à célula, isto é, a uma execução do corpo mais interno:
para linha de 0 até 1
para coluna de 0 até 2
visite matriz[linha][coluna]
| Visita | Linha | Coluna | Posição |
|---|---|---|---|
| 1 | 0 | 0 | [0][0] |
| 2 | 0 | 1 | [0][1] |
| 3 | 0 | 2 | [0][2] |
| 4 | 1 | 0 | [1][0] |
| 5 | 1 | 1 | [1][1] |
| 6 | 1 | 2 | [1][2] |
A coluna interna volta ao estado inicial quando o laço externo avança. Se a tabela omitir linha, duas visitas com coluna = 0 parecerão iguais. Veja a ordem completa em estruturas de repetição aninhadas.
Em funções, separe uma chamada da outra
Variáveis locais com o mesmo nome podem pertencer a chamadas diferentes. Acrescente uma coluna de chamada ou quadro de execução:
dobrar(3) retorna 6
dobrar(5) retorna 10
| Chamada | Argumento | Parâmetro local | Retorno |
|---|---|---|---|
| 1 | 3 | 3 | 6 |
| 2 | 5 | 5 | 10 |
Não continue a segunda chamada na mesma linha da primeira como se o parâmetro local tivesse apenas mudado de 3 para 5. A primeira variável local deixa de pertencer ao contexto ativo quando a função retorna; a segunda chamada cria outro contexto. A aula sobre escopo de variáveis explica essa fronteira.
Em recursão, use uma linha por chamada e inclua profundidade, argumento recebido, estado antes da chamada interna e valor devolvido. A ordem de retorno é inversa à ordem de entrada.
A tabela manual e o depurador observam o mesmo tipo de evidência
Um depurador executa o programa de verdade e permite avançar por instruções, pausar em breakpoints e inspecionar variáveis locais ou expressões escolhidas. Uma tabela manual prevê e registra o estado sem depender da ferramenta.
As duas abordagens podem ser comparadas:
| Tabela manual | Depurador |
|---|---|
| linha da tabela | pausa após um passo |
| coluna de variável | painel de variáveis ou watch |
| coluna de condição | expressão avaliada |
| chamada identificada | quadro na pilha de chamadas |
Observe o momento da pausa. Em muitos depuradores, a instrução destacada é a próxima a executar. Se a execução está parada em soma = soma + nota, a soma exibida ainda pode ser a anterior à atribuição.
Evite editar valores durante uma observação inicial. Alterar uma variável no depurador muda o experimento e pode fazer a execução seguir por um caminho que o programa normal nunca seguiria.
Erros que tornam o rastro ambíguo
Misturar valores de antes e depois
Declare o ponto de captura e mantenha-o. Se precisar observar uma instrução específica, crie colunas “antes” e “depois” ou uma tabela auxiliar.
Criar uma linha somente quando algo muda
Uma decisão falsa também é execução. Omiti-la esconde caminhos e faz parecer que itens não foram visitados.
Deixar células vazias sem convenção
Use — para ausência ou não aplicável e repita valores que permaneceram iguais.
Registrar o resultado sem a condição
Se uma variável muda apenas em um ramo, a coluna da condição explica por que ela mudou ou permaneceu.
Misturar estados de chamadas ou iterações
Inclua índice, coordenadas, profundidade ou identificador de chamada suficiente para distinguir cada contexto.
Produzir uma tabela maior que a pergunta
Rastreie o menor caso que exercita o comportamento investigado. Para coleções extensas, reduza a entrada sem eliminar o caminho relevante.
Pratique com estoque acumulado
Considere este algoritmo:
movimentos = [5, -2, 4, -8]
estoque = 3
menor_estoque = estoque
para cada movimento
estoque = estoque + movimento
se estoque < menor_estoque
menor_estoque = estoque
Produza uma tabela que contenha:
- estado inicial;
- índice e movimento atual;
- estoque antes e depois da atualização;
- resultado de
estoque < menor_estoque; - menor estoque ao final de cada iteração;
- resultado final esperado.
Depois mova, propositalmente, a comparação para antes da atualização de estoque. Execute o mesmo rastro e identifique a primeira linha em que menor_estoque diverge.
Seu registro está verificável se outra pessoa consegue reconstruir a ordem das instruções sem executar o código.
O que você deve guardar
Uma boa tabela de rastreamento possui um ponto de captura explícito, uma linha para cada evento relevante e somente as colunas necessárias para explicar o comportamento. Ausência, permanência e mudança precisam ser distinguíveis.
Comece pelo estado inicial, avance na ordem real, registre condições falsas e separe contextos de laços e funções. Compare o estado esperado com o observado de cima para baixo: a primeira divergência costuma ser mais útil do que o resultado final incorreto.
O próximo passo é aprender como criar casos de teste que exercitem comportamentos diferentes sem repetir entradas sem propósito.
Referências
- MIT OpenCourseWare — Testing, Debugging, Exceptions and Assertions. Acesso em 22 set. 2026.
- MIT OpenCourseWare — Foundations of Software Engineering: Recitation 1. Acesso em 22 set. 2026.
- Microsoft Learn — Inspect variables and return values in the Visual Studio debugger. Acesso em 22 set. 2026.
- Microsoft Learn — Navigate code with the debugger. Acesso em 22 set. 2026.
- Python Documentation —
pdb: The Python Debugger. Acesso em 22 set. 2026.