Skip to main content

Como escrever testes em Python usando doctest

Escrito por

Mannan Tirmizi

21 de novembro de 2022

0 minutos de leitura

Como desenvolvedores, muitas vezes escrevemos casos de teste e comentários para explicar nosso código. Os comentários melhoram a legibilidade e a qualidade da base de código. Comentários detalhados podem nos lembrar por que implementamos determinada funcionalidade. Eles também ajudam outros programadores a entender, manter, usar e expandir bases de código.

Uma das boas práticas é escrever primeiro os comentários e os casos de teste das suas funções. Isso ajuda você a produzir código de melhor qualidade e a manter em vista os diferentes casos extremos e requisitos da função. No entanto, os métodos tradicionais consomem muito tempo, pois precisamos preparar um arquivo separado para os casos de teste e escrever funções extensas para cada teste.

A ferramenta doctest do Python é muito útil nessas situações. A comunidade de código aberto desenvolveu o módulo doctest para oferecer uma estrutura eficiente de testes durante o desenvolvimento. Podemos usar o doctest para escrever testes para o código da função, definindo os valores de entrada e saída. Assim, economizamos tempo e esforço ao criar código de alta qualidade.

Parece ótimo, mas como escrever um doctest em Python? Neste artigo, vamos mostrar como configurar, escrever e testar seu primeiro doctest — com todas as informações de que você precisa para começar.

Como escrever seu primeiro doctest

Antes de começar a escrever seu primeiro doctest em Python, verifique se você tem o Python 3 e um ambiente de programação adequado instalados no computador, como o Visual Studio Code (VS Code). Neste tutorial, vamos usar o VS Code como ambiente de desenvolvimento integrado (IDE).

Configurando a IDE

Depois de instalar o Python 3, verifique se a instalação foi concluída com sucesso. No Windows, digite o seguinte trecho de código no prompt de comando:

py -3 --version

No macOS ou Unix, abra o terminal e digite o seguinte comando:

python3 --version.

Em seguida, baixe a IDE Visual Studio Code.

Abra o assistente de instalação e siga as instruções na tela para instalar o VS Code.

Depois de abrir o VS Code, baixe a extensão Python na guia Extensões. Agora, você já pode usar Python no VS Code.

Conheça as docstrings

O Python tem um recurso chamado docstring. As docstrings são literais de string que usamos na declaração de uma função, classe ou módulo para incluir comentários e casos de teste nas funções. Por isso, elas são essenciais tanto para a documentação quanto para os testes.

Podemos escrever uma docstring entre três aspas:

"""

Depois da docstring, podemos escrever os comentários e os testes, também entre três aspas.

"""

Neste tutorial, vamos aprender a sintaxe dos casos de teste e dos comentários. À primeira vista, uma docstring e um comentário podem parecer iguais. No entanto, eles têm finalidades diferentes. Os comentários explicam a implementação do código, enquanto as docstrings documentam classes, métodos e funções. Elas ajudam outros programadores a entender a finalidade de uma função e como usá-la no trabalho.

O módulo doctest identifica docstrings em definições de funções ou classes. Para distinguir os casos de teste dos comentários, colocamos o símbolo >>> antes dos testes na docstring.

Abra a linha de comando do seu sistema operacional e digite python3.

Prompt de comando do Windows exibindo o interpretador interativo do Python 3.9.13 no prompt >>>

O shell interativo do Python 3 usa o símbolo >>> como prompt e retorna a saída sem esse símbolo. Suponha que imprimimos um valor. A sessão interativa fica assim:

Terminal interativo do Python exibindo `print(5)` e a saída `5`.

O módulo doctest procura e identifica na docstring padrões que se parecem com sessões interativas do Python. Quando os encontra, executa-os. Os doctests precisam estar na docstring inicial, logo após a chamada da função ou o cabeçalho do método. Evite espaços extras ao escrever o doctest para prevenir erros ou falhas inesperados.

Escrevendo um doctest

Para usar doctests, primeiro vamos escrever um exemplo de código. Neste tutorial, vamos criar um módulo simples chamado square.py, com uma função chamada square. A função calcula o quadrado do valor de entrada.

def square(x):
    return x*x

Agora, incluímos uma docstring na função. Ela contém a documentação que descreve o que a função faz, além de dois casos de teste com os valores de entrada e as saídas esperadas. Esses valores são usados para testar o resultado processado.

def square(x):
    """
    This function returns the square of the input.
    >>> square(2)
    4
    >>> square(5)
    25
    """
    return x*x

Como o resultado processado é testado?

O módulo doctest analisa a docstring e gera texto. Ele executa o texto analisado como um comando do shell do Python. Em seguida, compara o resultado com o valor esperado indicado na docstring.

Como executar um doctest

Para executar o doctest usando nosso módulo, square.py, adicionamos a função testmod do doctest. A função doctest.testmod testa o módulo m ou o módulo "_main_", caso m não seja informado. Essa função é necessária para executar o doctest.

def square(x):
    """
    This function returns the square of the input.
    >>> square(2)
    4
    >>> square(5)
    25
    """
    return x*x

if __name__ == "__main__":
    import doctest
    doctest.testmod() #test the whole module.

Depois, basta executar o módulo square.py no terminal com o comando:

python square.py

Como square.py tem apenas uma função, o módulo doctest testa somente essa função.

Terminal do PowerShell no Visual Studio Code mostrando o comando “python square.py” executado no diretório da Área de Trabalho do Windows

Como não há saída, todos os testes passaram. Se algum teste falhar, o erro aparecerá no terminal e poderemos resolvê-lo. Para ver o log, alteramos o script adicionando -v:

python square.py -v
Terminal do PowerShell mostrando o resultado do doctest do Python para square.py: dois testes aprovados e nenhum reprovado.

Os logs mostram os resultados com mais detalhes, incluindo os índices de sucesso e falha dos testes. Também podemos usar um atalho prático para executar a função testmod sem a função main: basta executar diretamente o módulo doctest, que faz parte da biblioteca padrão. Para isso, passamos o nome do módulo à interface de linha de comando:

python -m doctest -v square.py

Agora, vamos ampliar um pouco o exemplo anterior. E se você quiser especificar os tipos de dados de entrada e saída da função? Para isso, basta fazer uma pequena alteração na docstring. Usando o exemplo anterior, é só adicionar:

:param a: int
:return: int

Assim, nossa docstring fica:

def square(x):
    """
    This function returns the square of the input.
    :param a: int
    :return: int
    >>> square(2)
    4
    >>> square(5)
    25
    """
    return x*x

Se tivermos mais de um parâmetro de entrada, podemos ajustar :param. Suponha que tenhamos dois parâmetros de entrada. A docstring correspondente seria:

:param a: int
:param b: int
:return: int

Podemos fazer o mesmo para quantos parâmetros de entrada forem necessários.

Parabéns! Você acabou de escrever um doctest.

Conclusão

Neste artigo, apresentamos o módulo doctest do Python e mostramos como os doctests podem melhorar a qualidade do código e contribuir para uma abordagem melhor de programação.

Também mostramos como incluir doctests em funções e executá-los usando o arquivo de código e o terminal — além de demonstrar como é fácil usar o módulo doctest na programação.

A abordagem clássica para testar funções é escrever um script independente com os casos de teste. Os doctests eliminam a necessidade desses scripts e permitem testar o código com mais eficiência. Em resumo, eles simplificam os testes e melhoram a qualidade do código Python.

Comece a jogar Capture the Flag

Aprenda a resolver desafios de Capture the Flag assistindo à gravação sob demanda do nosso workshop virtual introdutório.

Leia mais

Blog

Modelos de ponta encontraram as vulnerabilidades. Só o atacante encontrou as cadeias.

A análise estática encontrou as falhas, mas só os testes de ataque em aplicações ativas provaram como elas poderiam ser encadeadas para causar invasões. Uma comparação entre Evo COS, Claude Security e Claude Code Security.

feature insights context
Blog

Os ataques autônomos já chegaram. A defesa precisa acompanhar o ritmo.

Os atacantes autônomos estão reduzindo o tempo disponível para a defesa. Saiba como a descoberta, a correção, a validação e a prevenção contínuas ajudam as equipes de segurança a acompanhar esse ritmo.

Blog

Por que agentes de programação com IA continuam criando falhas de controle de acesso

Agentes de programação com IA podem gerar uma lógica de autorização que compila e passa pela revisão, mas permite que um tenant acesse os dados de outro. Saiba por que é difícil detectar falhas de controle de acesso e como evitá-las.