Trilha de aprendizado · Nível 8 · Tutorial 6

Investigar falhas com pontos de interrupção

Usar o depurador para acompanhar uma execução reproduzível, localizar a origem de valores incorretos e proteger a correção com um teste de regressão.

  • Nível: Intermediário
  • Duração: 20 min
  • 8 passos
Investigar falhas com pontos de interrupção

O que você vai percorrer

  1. Tornar a falha reproduzível Crie um caso pequeno e determinístico, confirme a divergência pelo programa e pelo teste e registre uma hipótese inicial sem tratá-la como causa comprovada. 2 min
  2. Pausar a execução com breakpoint() Insira uma pausa temporária antes da região suspeita e identifique a próxima linha que será executada. 3 min
  3. Inspecionar valores sem interferir Use o comando p para consultar o estado da execução pausada e diferencie observações seguras de expressões que podem alterar os dados investigados. 2 min
  4. Controlar o avanço da execução Escolha entre avançar no quadro atual, entrar em uma chamada e continuar a execução, alternando esses comandos com a inspeção de valores. 3 min
  5. Navegar pelos quadros da pilha Relacione os valores locais de funções encadeadas navegando pela pilha sem executar novas linhas. 2 min
  6. Inspecionar uma falha de teste com --pdb Entrar no depurador após a falha de um teste, relacionar o assert aos valores disponíveis e reconhecer quando uma nova execução é necessária. 3 min
  7. Localizar a primeira divergência Reposicione a pausa antes das funções suspeitas e compare o estoque antes e depois de cada operação para identificar onde o valor se desvia pela primeira vez. 3 min
  8. Aplicação final: corrigir e proteger o comportamento Aplique a correção mínima, preserve o caso como teste de regressão e verifique a suíte completa. 3 min

O que você vai aprender

  • Reduzir uma falha a uma entrada ou teste que a reproduza de forma consistente.
  • Interromper a execução com breakpoint e inspecionar variáveis sem alterar deliberadamente o estado.
  • Avançar por linhas e chamadas, navegando pelos quadros da pilha.
  • Confirmar uma hipótese sobre a causa do defeito e manter um teste que detecte sua reintrodução.

Antes de começar

  • Selecionar casos de teste e verificar exceções
  • Tratar exceções com try, except, else e finally
  • Decompor um programa em funções com responsabilidades claras

Passo 1 de 8

Tornar a falha reproduzível

Crie um caso pequeno e determinístico, confirme a divergência pelo programa e pelo teste e registre uma hipótese inicial sem tratá-la como causa comprovada.

Um caso fixo para investigar

Comece pelo comportamento esperado

Uma reserva parte de 10 unidades e solicita 3 unidades. Pelo contrato da operação, o saldo deveria ser 7, independentemente de como o código foi implementado.

Porém, o programa informa 4. Esse é o sintoma observado — ainda não é uma explicação da causa. Para investigá-lo, manteremos apenas um produto, uma quantidade fixa e uma chamada que preserve a falha.

A divergência do caso mínimo

Diagrama mostrando um estoque inicial de 10 unidades, uma reserva de 3 unidades, o saldo esperado de 7 e o saldo obtido de 4.

A mesma entrada produz uma diferença objetiva entre o contrato esperado e o resultado observado.

Dica

Reduzir sem mascarar

Reduzir o cenário não significa reescrever a implementação suspeita. Remova apenas dados e chamadas que não sejam necessários para reproduzir a divergência, preservando a entrada e o comportamento esperado.

Crie os dois arquivos

Prepare o caso no seu computador

Na mesma pasta, crie estoque.py e test_estoque.py com os conteúdos completos abaixo. Não corrija nem simplifique as funções internas neste momento: primeiro precisamos observar a falha de maneira consistente.

estoque.py

Programa curto de reserva de estoque com uma entrada fixa.

python
def separar_itens(estoque, produto, quantidade):
    estoque[produto] -= quantidade


def confirmar_reserva(estoque, produto, quantidade):
    estoque[produto] -= quantidade


def reservar(estoque, produto, quantidade):
    separar_itens(estoque, produto, quantidade)
    confirmar_reserva(estoque, produto, quantidade)
    return estoque[produto]


if __name__ == "__main__":
    estoque = {"caderno": 10}
    saldo = reservar(estoque, "caderno", 3)
    print(f"Saldo final: {saldo}")

test_estoque.py

O resultado esperado vem da regra: reservar 3 das 10 unidades deve deixar 7.

python
from estoque import reservar


def test_reserva_reduz_saldo_uma_vez():
    estoque = {"caderno": 10}

    saldo = reservar(estoque, "caderno", 3)

    assert saldo == 7
    assert estoque == {"caderno": 7}

Reproduza a mesma divergência

Execute programa e teste

No terminal, a partir da pasta que contém os dois arquivos, execute primeiro:

python estoque.py

Depois selecione somente o caso condutor:

python -m pytest test_estoque.py::test_reserva_reduz_saldo_uma_vez

As duas execuções devem partir do mesmo estoque inicial e expor a mesma divergência.

Exemplo

Evidência esperada

O programa apresenta Saldo final: 4. O pytest informa que a expectativa saldo == 7 falhou porque o valor obtido foi 4.

Agora há três fatos separados:

  • entrada mínima: estoque 10 e reserva 3;
  • resultado esperado: saldo 7;
  • sintoma observado: saldo 4.

A saída exata do relatório do pytest pode variar entre versões, mas a diferença entre 7 e 4 deve permanecer.

Formule uma hipótese investigável

Registre o ponto de partida

Descreva a entrada mínima, o resultado esperado, o resultado obtido e uma hipótese que possa ser confrontada durante a execução. Evite corrigir o código ou afirmar que já encontrou a causa.

Escreva pelo menos 80 caracteres (0/80).

Passo 2 de 8

Pausar a execução com breakpoint()

Insira uma pausa temporária antes da região suspeita e identifique a próxima linha que será executada.

Uma pausa antes da região suspeita

Pare antes de observar

Um ponto de interrupção pausa uma execução específica para que você examine o que está acontecendo. Ele não corrige o programa nem muda o resultado esperado.

No estoque.py do caso anterior, insira temporariamente breakpoint() imediatamente antes da chamada que inicia a região suspeita. Assim, a pausa acontece antes que essa chamada produza seus efeitos.

Posição da pausa

Preserve o código e os nomes do arquivo anterior. Acrescente somente a linha destacada pela posição mostrada neste trecho:

python
# Preparação da entrada fixa do caso anterior

breakpoint()
saldo_obtido = processar_reserva(estoque, produto, quantidade)

# Apresentação do resultado

Dica

Pausa temporária

Trate breakpoint() como um instrumento de investigação. Depois de concluir o diagnóstico, você deverá remover essa chamada do programa.

Reconhecer a posição atual

Execute pelo terminal

Salve o arquivo e execute python estoque.py. Na configuração padrão do Python, breakpoint() abre o depurador pdb no terminal.

A parada terá uma forma semelhante a esta:

> .../estoque.py(XX)<module>()
-> saldo_obtido = processar_reserva(...)
(Pdb)

A primeira linha identifica o arquivo, o número da linha e o contexto atual. A seta aponta para a linha que ainda será executada. Portanto, os efeitos da chamada indicada ainda não ocorreram nessa parada.

Código e terminal apontam para a mesma posição

A pausa ocorre entre a preparação da entrada e a chamada suspeita.

Diagrama dividido mostrando, à esquerda, um marcador de pausa antes de uma chamada de função no código e, à direita, o terminal apontando para essa mesma chamada como próxima linha a executar.

O marcador fica antes da chamada; a seta do depurador indica a próxima linha, não uma operação já concluída.

Dica

Encerrar a investigação

No prompt (Pdb), digite q e pressione Enter para sair do depurador e interromper essa execução. Execute python estoque.py novamente quando precisar começar uma investigação nova a partir da entrada fixa.

Escolha a pausa correta

Antes ou depois da chamada?

Você suspeita que processar_reserva(...) introduz o saldo incorreto. Qual opção permite examinar o estado anterior à chamada e interpreta corretamente a seta exibida pelo depurador?

Passo 3 de 8

Inspecionar valores sem interferir

Use o comando p para consultar o estado da execução pausada e diferencie observações seguras de expressões que podem alterar os dados investigados.

Consultar o estado na pausa

O comando p

No prompt (Pdb), use p expressão para avaliar e apresentar uma expressão no quadro atual. Comece por consultas simples: parâmetros, variáveis locais, entradas de dicionários e comparações. Isso permite confrontar o estado observado com o que sua hipótese previa.

Inspeção do caso reproduzível

Com a execução pausada antes da chamada suspeita, consulte os dados sem modificá-los:

text
(Pdb) p estoque
{'caderno': 10}
(Pdb) p produto
'caderno'
(Pdb) p quantidade
3
(Pdb) p estoque[produto]
10
(Pdb) p estoque[produto] == 10
True

Observar sem modificar

Comparação entre uma consulta que apenas observa um valor do dicionário e uma chamada que remove um item durante a depuração.

À esquerda, a lupa representa uma consulta ao estado. À direita, uma mão retirando um elemento representa uma expressão que interfere na execução investigada.

Evitar contaminar a investigação

p avalia a expressão

O comando p não é um visualizador passivo: ele executa a expressão fornecida. Consultar estoque[produto] ou comparar valores é adequado. Já chamar métodos que alteram coleções ou funções que executam ações do programa pode mudar justamente o estado que você pretende investigar.

Consultas e interferências

Compare expressões de observação com expressões que modificam o dicionário:

text
# Consultas simples
(Pdb) p estoque[produto]
(Pdb) p quantidade > 0
(Pdb) p estoque[produto] - quantidade

# Evite durante a inspeção
(Pdb) p estoque.pop(produto)
(Pdb) p estoque.update({produto: 999})

Atenção

Alterou o estado sem querer?

Encerre a sessão com q e inicie novamente com python estoque.py. A entrada fixa reproduzível devolve um estado confiável para a investigação. Não use o valor já contaminado como evidência.

Escolha uma consulta segura

Inspeção sem interferência

Qual comando consulta o saldo de caderno sem alterar deliberadamente o dicionário estoque?

Registre evidências

Compare previsão e observação

Na execução local, consulte com p os valores de produto, quantidade e estoque[produto]. Compare-os com o que você previa para esse ponto da execução e registre sua conclusão provisória.

Escreva pelo menos 60 caracteres (0/60).

Passo 4 de 8

Controlar o avanço da execução

Escolha entre avançar no quadro atual, entrar em uma chamada e continuar a execução, alternando esses comandos com a inspeção de valores.

Três formas de prosseguir

Escolha conforme a pergunta

Depois de pausar, use o comando que responde à sua pergunta:

  • n (next): executa a linha indicada e para na próxima linha do quadro atual. Se a linha chama uma função, a função inteira é executada sem pausas internas.
  • s (step): executa o próximo passo e entra em uma função Python chamada pela linha.
  • c (continue): retoma a execução até outro ponto de interrupção ou até o programa terminar.

Use n quando importa o efeito da chamada e s quando importa como ela produz esse efeito.

Fluxos de n, s e c

Diagrama comparando os caminhos do depurador ao usar n, s e c em uma chamada de função.

Na linha de chamada, n retorna ao chamador após executar a função; s entra na função auxiliar; c segue até outra interrupção ou o término.

Avançar não significa ignorar

Compare antes e depois

Uma chamada ultrapassada com n continua sendo executada. Seus retornos e alterações em objetos permanecem no programa; apenas não acompanhamos suas linhas internas.

No caso de estoque, pause na linha que chama uma função auxiliar. Inspecione o saldo com p, avance com n e consulte o mesmo valor novamente:

Sequência no pdb

Digite um comando por vez. Substitua os nomes apenas se sua versão do caso usar outros nomes.

text
(Pdb) p estoque[produto]
(Pdb) n
(Pdb) p estoque[produto]

A diferença em movimento

Observe onde a execução para depois de cada comando.

n permanece no chamador, s entra na função e c segue sem parar em cada linha.

Dica

Inspecione nos pontos decisivos

Alterne p com n ou s. Compare o valor imediatamente antes e depois da operação relevante, em vez de avançar muitas linhas e perder o primeiro momento da mudança.

Qual comando responde à pergunta?

Associe comando e objetivo

Relacione cada comando do pdb ao objetivo de investigação.

Toque em um item e depois no par correspondente.

Observe onde o valor muda

Prática no seu computador

Execute novamente python estoque.py com o breakpoint() antes da chamada auxiliar investigada. Na pausa:

  1. Consulte o saldo atual com p estoque[produto].
  2. Use n para executar a chamada inteira.
  3. Consulte novamente o mesmo saldo.
  4. Inicie uma nova execução e use s na mesma chamada para entrar nela.
  5. Alterne n e p estoque[produto] até observar a operação que muda o valor.
  6. Use c para prosseguir ou q para encerrar a investigação.

Não faça atribuições nem chame operações mutadoras durante a inspeção.

Registre a evidência

Em qual operação o saldo mudou? Relate os valores observados antes e depois e explique como n, s e p ajudaram a localizar essa mudança.

Escreva pelo menos 40 caracteres (0/40).

Passo 5 de 8

Navegar pelos quadros da pilha

Relacione os valores locais de funções encadeadas navegando pela pilha sem executar novas linhas.

Cada chamada tem seu contexto

Quadros da pilha

Quando uma função chama outra, cada chamada ativa possui um quadro: o contexto que reúne sua posição no código e seus nomes locais.

No pdb, use w para exibir a pilha. O marcador > identifica o quadro selecionado, no qual comandos como p quantidade serão avaliados.

Chamador e função interna

Diagrama vertical com o quadro da função interna acima do quadro de sua chamadora. Setas indicam u em direção ao chamador e d em direção à função interna.

u seleciona um quadro mais antigo, em direção aos chamadores; d retorna a um quadro mais recente, em direção à chamada interna.

Consultar valores em quadros diferentes

Exemplo de navegação no pdb

A pilha está pausada dentro da função auxiliar. Observe como o nome disponível para p muda com o quadro selecionado.

text
(Pdb) w
  estoque.py(...)reservar()
> estoque.py(...)aplicar_reserva()

(Pdb) p quantidade
2

(Pdb) u
> estoque.py(...)reservar()

(Pdb) p quantidade_solicitada
2

(Pdb) d
> estoque.py(...)aplicar_reserva()

(Pdb) p quantidade
2

Dica

Navegar não é executar

Os comandos u e d apenas mudam o contexto selecionado para inspeção. Eles não executam linhas, não desfazem operações e não fazem o programa voltar no tempo. Use w novamente quando precisar confirmar sua posição na pilha.

Escolha a direção

Do quadro interno ao chamador

Você está no quadro da função auxiliar e quer consultar uma variável local existente apenas na função que a chamou. Qual comando deve usar primeiro?

O que muda ao navegar?

Quadro não é viagem no tempo

Após usar u, as operações realizadas pela função interna são desfeitas e podem ser executadas novamente.

Passo 6 de 8

Inspecionar uma falha de teste com --pdb

Entrar no depurador após a falha de um teste, relacionar o assert aos valores disponíveis e reconhecer quando uma nova execução é necessária.

Entrar no depurador após a falha

Deixe o pytest provocar a parada

Remova do arquivo estoque.py o breakpoint() temporário usado anteriormente. Agora a pausa deve acontecer por causa da falha do teste, não durante a execução normal do programa.

No terminal, dentro da pasta do projeto, execute o arquivo de teste com --pdb. A entrada continua sendo a mesma do caso reproduzível.

Executar o teste selecionado

Se test_estoque.py contém o caso reproduzível deste tutorial, execute:

bash
python -m pytest test_estoque.py --pdb

Dica

O que esperar

O pytest primeiro apresenta a diferença do assert e o rastreamento. Em seguida, abre o prompt (Pdb) no contexto da falha. A aparência exata da saída pode variar um pouco entre versões do pytest.

Relacionar diferença, quadro e valores

Três evidências complementares

A diferença do assert informa que o teste obteve um saldo diferente do esperado. O rastreamento mostra onde a verificação falhou. No prompt do depurador, p permite consultar os nomes disponíveis no quadro selecionado e confirmar o valor incorreto.

Essa confirmação localiza o sintoma no teste, mas ainda não prova qual operação produziu o saldo incorreto.

Alcance da inspeção pós-falha

A inspeção começa no quadro em que o assert falhou. Funções que já retornaram normalmente não permanecem disponíveis nessa pilha.

Diagrama de uma falha de teste conectada aos quadros ainda disponíveis, enquanto quadros de funções já encerradas aparecem fora do alcance.

O depurador mostra os quadros preservados pelo rastreamento da falha, não um histórico completo da execução.

Atenção

A linha do assert não é necessariamente a causa

O assert é o lugar onde a divergência foi percebida. Se a função testada retornou normalmente antes da verificação, seus quadros já foram encerrados e não podem ser recuperados por essa sessão do depurador.

Explorar apenas os quadros disponíveis

Navegue e inspecione

No prompt (Pdb), use os comandos já praticados. w mostra a pilha e marca o quadro selecionado. u seleciona um quadro mais antigo, na direção dos chamadores; d volta para um quadro mais recente. Depois de mudar de quadro, use p para consultar os nomes disponíveis naquele contexto.

A pilha pode incluir quadros internos do pytest. Priorize o quadro de test_estoque.py, pois ele contém os dados do caso. Navegar entre quadros não executa linhas nem recupera chamadas encerradas.

Sequência de investigação no prompt

Substitua os nomes do exemplo pelos nomes exibidos no seu teste quando necessário.

text
(Pdb) w
(Pdb) p estoque
(Pdb) p saldo_obtido
(Pdb) u
(Pdb) d
(Pdb) c

Dica

Quando usar c

O comando c deixa essa inspeção e permite que o pytest prossiga. Ele não retorna ao interior de uma função que já terminou. Para observar um momento anterior, será preciso iniciar outra execução e posicionar um breakpoint() antes desse momento.

Verifique o limite da inspeção

Quadros e tempo de execução

Depois que a função testada retorna normalmente e o assert falha, o comando u permite reabrir o quadro encerrado dessa função e acompanhar suas linhas anteriores.

Decida o próximo passo

No prompt aberto pela falha, p saldo_obtido apresenta 4, enquanto o teste esperava 7. O comando w mostra o quadro do teste e quadros internos do pytest, mas não mostra o quadro da função de reserva. O que essa observação confirma e qual deve ser o próximo passo para descobrir onde o valor se desviou?

Escreva pelo menos 80 caracteres (0/80).

Passo 7 de 8

Localizar a primeira divergência

Reposicione a pausa antes das funções suspeitas e compare o estoque antes e depois de cada operação para identificar onde o valor se desvia pela primeira vez.

Do sintoma ao ponto de investigação

Pause antes, não onde o erro aparece

O teste percebe o problema no assert: esperava saldo 7, mas recebeu 4. Esse é o sintoma, não necessariamente a origem.

Combine o rastreamento com os valores já observados para escolher uma pausa anterior ao retorno incorreto. No caso de estoque, a região suspeita é a fronteira entre reservar() e baixar_estoque(), onde duas funções encadeadas podem alterar o mesmo dicionário.

A primeira mudança incompatível

Acompanhe o mesmo estoque em três momentos. A investigação deve localizar a transição que transforma um estado ainda correto no primeiro estado incompatível com o resultado esperado.

Diagrama com dez caixas de estoque, depois sete e finalmente quatro; a segunda retirada de três caixas aparece destacada como a transição suspeita.

O saldo 4 é percebido no teste, mas nasce na segunda retirada: a primeira redução, de 10 para 7, ainda está de acordo com o esperado.

Comparar o estado antes e depois

Reposicione o breakpoint

No seu estoque.py, remova a pausa temporária anterior e deixe breakpoint() imediatamente antes da chamada a baixar_estoque(). Mantenha o defeito por enquanto: o objetivo desta execução é coletar evidências, não corrigir o código.

Versão investigada de estoque.py

Use este código para manter o mesmo caso reproduzível durante a investigação.

python
def baixar_estoque(estoque, produto, quantidade):
    estoque[produto] -= quantidade


def reservar(estoque, produto, quantidade):
    breakpoint()
    baixar_estoque(estoque, produto, quantidade)
    estoque[produto] -= quantidade
    return estoque[produto]


def main():
    estoque = {"caderno": 10}
    saldo = reservar(estoque, "caderno", 3)
    print(f"Saldo esperado: 7; saldo obtido: {saldo}")


if __name__ == "__main__":
    main()

Sessão de investigação

Execute python estoque.py e informe estes comandos, um de cada vez. As linhas iniciadas por # descrevem o resultado esperado e não precisam ser digitadas.

text
p estoque[produto]
# 10

n
p estoque[produto]
# 7

n
p estoque[produto]
# 4

q

Interpretar a evidência

Exemplo

Hipótese, observação e conclusão

Hipótese: a quantidade reservada pode estar sendo abatida mais de uma vez nas funções encadeadas.

Observação decisiva: antes da chamada, o saldo é 10. Depois de baixar_estoque(), passa a 7, que já corresponde ao resultado esperado. Após estoque[produto] -= quantidade em reservar(), passa a 4.

Conclusão: a segunda subtração introduz a primeira divergência. O teste apenas percebe o saldo incorreto depois que reservar() retorna.

Atenção

Não force o resultado no depurador

Não atribua 7 ao saldo nem modifique o dicionário para fazer o teste passar. Isso esconderia a origem do defeito e contaminaria a execução. Se alterar o estado acidentalmente, encerre com q e repita o caso desde o início.

Registre seu diagnóstico

Explique a primeira divergência

Com base na sessão do depurador, identifique a operação que introduz o saldo incorreto. Apresente os valores observados antes e depois dela e explique por que essa evidência confirma um abatimento duplicado, em vez de apenas repetir a mensagem do teste.

Escreva pelo menos 100 caracteres (0/100).

Passo 8 de 8

Aplicação final: corrigir e proteger o comportamento

Aplique a correção mínima, preserve o caso como teste de regressão e verifique a suíte completa.

Corrija a origem, não a expectativa

Uma única operação deve realizar o abatimento

A investigação confirmou que a quantidade reservada era abatida duas vezes: uma na função auxiliar e outra na função chamadora. Em estoque.py, mantenha o abatimento na função responsável por alterar o estoque e remova somente a segunda instrução estoque[produto] -= quantidade da função chamadora.

Não altere o saldo esperado para aceitar o defeito. Para estoque inicial 10 e reserva 3, o contrato continua exigindo saldo 7.

Mantenha o caso como teste de regressão

Confirme que test_estoque.py preserva a entrada que revelou o defeito e verifica o comportamento público esperado.

python
from estoque import reservar


def test_reserva_abate_quantidade_uma_vez():
    estoque = {"caderno": 10}

    reservar(estoque, "caderno", 3)

    assert estoque["caderno"] == 7

Dica

Correção mínima

Mude apenas a operação responsável pelo abatimento duplicado. O teste deve permanecer com a expectativa definida antes da correção: saldo 7.

Verifique antes de concluir

Da falha à aprovação

O mesmo teste forneceu duas evidências: na versão defeituosa, ele falhou porque encontrou saldo 4 em vez de 7; depois da correção, deve passar sem mudar a expectativa.

Remova todos os breakpoint() temporários de estoque.py. Em seguida, execute primeiro o arquivo de teste que reproduz a falha e depois todos os testes do projeto.

Execute as verificações sem pausas

No terminal, a partir da pasta que contém os arquivos do projeto, execute:

bash
python -m pytest test_estoque.py -q
python -m pytest

Ciclo completo da investigação

A correção só encerra a investigação depois que o caso reproduzível passa e os demais testes são executados.

Fluxo visual que começa com um teste falhando, passa por hipótese, breakpoint, inspeção, localização de um abatimento duplicado e termina com correção e testes aprovados.

Reproduzir → formular hipótese → pausar → inspecionar → localizar a origem → corrigir → verificar.

Consolide a investigação

Ordene o processo

Coloque as etapas da investigação na ordem adequada.

  1. Executar novamente o teste de regressão sem breakpoint().
  2. Formular uma hipótese sobre onde o valor se desvia.
  3. Executar os demais testes para procurar efeitos indesejados.
  4. Localizar a primeira operação incompatível com o esperado.
  5. Reproduzir a falha com uma entrada e uma expectativa fixas.
  6. Aplicar a menor correção que preserve o contrato público.
  7. Pausar e inspecionar a execução sem alterar o estado.

Registre suas evidências

Com base na sua execução local, relate: a causa do defeito, a observação decisiva, como o teste falhava antes, o resultado após a correção e o resultado dos demais testes.

Escreva pelo menos 120 caracteres (0/120).

Investigação concluída

Resumo

O que você consolidou

Você concluiu uma investigação sem ajustar artificialmente o estado nem enfraquecer a expectativa do teste.

  • Uma entrada fixa e uma expectativa independente tornaram a falha reproduzível.
  • Breakpoints, inspeção, avanço e navegação pela pilha ajudaram a localizar a primeira divergência.
  • A correção mínima removeu o abatimento duplicado e preservou o contrato público.
  • O caso que expôs o defeito permaneceu como teste de regressão.
  • A execução da suíte procurou efeitos indesejados, sem garantir ausência absoluta de defeitos.

Tutorial concluído

Parabéns! Você concluiu: Investigar falhas com pontos de interrupção

Você agora consegue reproduzir uma falha, acompanhar sua execução, localizar a origem de um valor incorreto e proteger a correção com um teste de regressão.

100 XP

Baixe o Aplicativo agora para ter acesso a + de 5000 cursos gratuitos, exercícios, certificado e muito conteúdo sem pagar nada!

  • Cursos online 100% gratuitos do início ao fim

    Milhares de cursos online em vídeo, ebooks e áudiobooks.

  • Mais de 60 mil exercícios gratuitos

    Para testar seus conhecimentos no decorrer dos cursos online

  • Certificado Digital gratuito válido em todo o Brasil

    Gerado diretamente na galeria de fotos do seu celular e enviado ao seu e-mail

Aplicativo Cursa na tela de ebook, na tela de curso em vídeo e na tela de exercícios do curso, mais o certificado de conclusão de curso