Como Verificar se uma Função Lança uma Exceção em Python

PythonBeginner
Pratique Agora

Introdução

Neste laboratório, você aprenderá como verificar se uma função levanta uma exceção em Python. O laboratório começa explorando exceções e como elas podem ocorrer dentro de funções. Você criará uma função Python simples que pode levantar um ZeroDivisionError e observará o traceback (rastreamento) quando a exceção ocorrer.

Em seguida, você implementará um bloco try-except para lidar com a exceção de forma elegante. Finalmente, você aprenderá como usar pytest.raises para testar se uma função levanta uma exceção específica (introdução opcional).

Explorar Exceções em Funções

Nesta etapa, você aprenderá sobre exceções e como elas podem ocorrer dentro de funções em Python. Compreender exceções é crucial para escrever código robusto e confiável. Exceções são eventos que interrompem o fluxo normal da execução de um programa. Elas podem ocorrer devido a várias razões, como entrada inválida, arquivo não encontrado ou erros de rede.

Vamos começar criando uma função Python simples que pode levantar uma exceção. Abra o editor VS Code no ambiente LabEx e crie um novo arquivo chamado exceptions_example.py no diretório ~/project.

## ~/project/exceptions_example.py
def divide(x, y):
    return x / y

print(divide(10, 2))
print(divide(5, 0))

Neste código:

  • Definimos uma função chamada divide que recebe dois argumentos, x e y, e retorna o resultado de x dividido por y.
  • Primeiro, chamamos a função divide com os argumentos 10 e 2, o que resultará em 5.0 sendo impresso no console.
  • Em seguida, chamamos a função divide com os argumentos 5 e 0. Isso causará um ZeroDivisionError porque a divisão por zero não é permitida.

Agora, vamos executar este script. Abra o terminal no VS Code (você pode encontrá-lo em "View" -> "Terminal") e execute o seguinte comando:

python ~/project/exceptions_example.py

Você verá uma saída semelhante a esta:

5.0
Traceback (most recent call last):
  File "/home/labex/project/exceptions_example.py", line 4, in <module>
    print(divide(5, 0))
  File "/home/labex/project/exceptions_example.py", line 2, in divide
    return x / y
ZeroDivisionError: division by zero

Como você pode ver, a primeira instrução print foi executada com sucesso, e o resultado 5.0 foi impresso. No entanto, quando a função divide foi chamada com y = 0, um ZeroDivisionError ocorreu, e o programa foi encerrado. O traceback mostra a sequência de chamadas de função que levaram à exceção, o que pode ser útil para depuração.

Este exemplo demonstra como as exceções podem ocorrer dentro de funções e como elas podem interromper o fluxo normal de um programa. Na próxima etapa, você aprenderá como lidar com exceções usando blocos try e except.

Implementar um Bloco try-except

Na etapa anterior, você viu como as exceções podem fazer com que um programa termine abruptamente. Para lidar com exceções de forma elegante e evitar falhas no programa, você pode usar blocos try e except.

Um bloco try permite que você inclua uma seção de código que pode levantar uma exceção. Se uma exceção ocorrer dentro do bloco try, o programa pulará para o bloco except correspondente, onde você pode lidar com a exceção.

Vamos modificar o arquivo exceptions_example.py para incluir um bloco try-except para lidar com o ZeroDivisionError. Abra o arquivo exceptions_example.py no editor VS Code e modifique-o da seguinte forma:

## ~/project/exceptions_example.py
def divide(x, y):
    try:
        result = x / y
        return result
    except ZeroDivisionError:
        return "Cannot divide by zero!"

print(divide(10, 2))
print(divide(5, 0))
print(divide(8, 4))

Neste código modificado:

  • Adicionamos um bloco try em torno da operação x / y. Isso significa que, se um ZeroDivisionError ocorrer durante a divisão, o programa pulará para o bloco except.
  • A linha except ZeroDivisionError: especifica que queremos lidar com exceções ZeroDivisionError.
  • Dentro do bloco except, retornamos a string "Cannot divide by zero!". Isso será impresso no console em vez de o programa travar.

Agora, vamos executar o script modificado. Abra o terminal no VS Code e execute o seguinte comando:

python ~/project/exceptions_example.py

Você verá uma saída semelhante a esta:

5.0
Cannot divide by zero!
2.0

Como você pode ver, o programa não trava mais ao dividir por zero. Em vez disso, o bloco except captura o ZeroDivisionError, e a mensagem "Cannot divide by zero!" é impressa. O programa então continua a ser executado, e a instrução print final também é executada com sucesso.

Blocos try-except também podem ser usados para lidar com outros tipos de exceções. Por exemplo, você pode usar um bloco try-except para lidar com exceções TypeError que podem ocorrer se você tentar realizar uma operação em tipos de dados incompatíveis. Você também pode ter vários blocos except para lidar com diferentes tipos de exceções.

Na próxima etapa, você aprenderá como usar pytest para testar exceções.

Testar com pytest.raises (Introdução Opcional)

Nesta etapa opcional, você terá uma breve introdução ao uso do pytest para testar exceções. pytest é um framework de teste popular para Python que simplifica o processo de escrita e execução de testes.

Primeiro, vamos instalar o pytest. Abra o terminal no VS Code e execute o seguinte comando:

pip install pytest

Este comando irá baixar e instalar o pytest e suas dependências.

Agora, vamos criar um arquivo de teste para nossa função divide. Crie um novo arquivo chamado test_exceptions.py no diretório ~/project.

## ~/project/test_exceptions.py
import pytest
from exceptions_example import divide

def test_divide_by_zero():
    with pytest.raises(ZeroDivisionError):
        divide(5, 0)

def test_divide_valid():
    assert divide(10, 2) == 5

Neste código:

  • Importamos o módulo pytest e a função divide do nosso arquivo exceptions_example.py.
  • Definimos uma função de teste chamada test_divide_by_zero. Esta função usa pytest.raises para afirmar que chamar divide(5, 0) levantará um ZeroDivisionError. O bloco with pytest.raises(ZeroDivisionError): garante que o teste só passará se um ZeroDivisionError for levantado dentro do bloco.
  • Definimos outra função de teste chamada test_divide_valid. Esta função afirma que chamar divide(10, 2) retorna o valor 5.

Para executar os testes, abra o terminal no VS Code e execute o seguinte comando:

pytest ~/project/test_exceptions.py

Você deve ver uma saída semelhante a esta:

============================= test session starts ==============================
platform linux -- Python 3.10.12, pytest-7.4.4, pluggy-1.3.0
rootdir: /home/labex/project
collected 2 items

test_exceptions.py ..                                                      [100%]

============================== 2 passed in 0.01s ===============================

A saída mostra que dois testes foram coletados e que ambos os testes passaram. Isso indica que nossa função divide está se comportando como esperado: ela levanta um ZeroDivisionError ao dividir por zero e retorna o resultado correto ao dividir por um número diferente de zero.

Este é um exemplo muito básico de como usar pytest para testar exceções. pytest tem muitos outros recursos que podem ajudá-lo a escrever testes mais abrangentes e eficazes.

Resumo

Neste laboratório, você começa explorando exceções em funções Python, entendendo que exceções são eventos que interrompem o fluxo normal de um programa. Você cria uma função divide que levanta um ZeroDivisionError ao dividir por zero. A execução do script demonstra como a exceção termina o programa e fornece um traceback para depuração.

O laboratório destaca a importância de entender exceções para escrever código robusto, mostrando um exemplo simples de uma função que pode levantar uma exceção e como observar o erro resultante e o traceback quando a exceção ocorre.