doctest no Python: teste exemplos

Publicado em: 15/08/2026
Tempo de leitura: 6 minutos
Notebook com código representando exemplos executáveis testados com doctest no Python

O módulo doctest no Python encontra trechos que parecem sessões interativas dentro de docstrings ou arquivos de texto, executa cada comando e compara a saída real com a saída documentada. Ele transforma exemplos em documentação executável e ajuda a impedir que tutoriais, mensagens de ajuda e snippets fiquem desatualizados.

O recurso funciona melhor com exemplos pequenos, determinísticos e fáceis de ler. Ele não substitui uma suíte completa de testes, especialmente para lógica complexa, estados compartilhados, integração com rede ou casos que exigem fixtures elaboradas.

Escreva o primeiro exemplo

Uma docstring pode incluir prompts >>> e a saída esperada.

def dobro(valor):
    """Retorna o dobro de um número.

    >>> dobro(4)
    8
    >>> dobro(-3)
    -6
    """
    return valor * 2

O texto precisa imitar uma sessão interativa. A saída esperada começa logo após o comando e termina quando aparece outro prompt ou uma linha em branco.

Execute com testmod

if __name__ == "__main__":
    import doctest
    doctest.testmod()

Ao executar o arquivo, nenhuma saída significa que todos os exemplos passaram. Use modo verboso para acompanhar cada tentativa:

python modulo.py -v

Em CI, verifique o código de saída ou use a integração com unittest para evitar sucesso silencioso após uma configuração incorreta.

Use a linha de comando

Também é possível executar o módulo diretamente:

python -m doctest modulo.py
python -m doctest -v modulo.py

Para arquivos que fazem parte de um pacote e usam imports relativos, importar o módulo pelo contexto correto costuma ser mais confiável do que passar um arquivo isolado.

Teste arquivos de documentação

testfile() lê exemplos de um arquivo textual, como Markdown ou reStructuredText.

import doctest

resultado = doctest.testfile(
    "guia.txt",
    module_relative=False,
)
print(resultado)

O arquivo é tratado como uma docstring gigante. Isso permite testar tutoriais sem colocar todos os exemplos no código-fonte.

Entenda o contexto de execução

Cada docstring normalmente recebe uma cópia rasa dos globais do módulo. Exemplos dentro da mesma docstring compartilham variáveis; exemplos de docstrings diferentes não compartilham o mesmo contexto.

def exemplo_estado():
    """
    >>> valores = [1, 2]
    >>> valores.append(3)
    >>> valores
    [1, 2, 3]
    """

Objetos mutáveis presentes no dicionário copiado ainda podem ser compartilhados por referência. Evite depender de estado global e limpe recursos após cada teste.

Forneça globais explícitos

globs e extraglobs permitem preparar nomes.

doctest.testfile(
    "exemplos.txt",
    globs={"Cliente": Cliente},
    extraglobs={"config": config_teste},
    module_relative=False,
)

Não inclua credenciais reais, conexões de produção ou objetos com efeitos irreversíveis. Use doubles, diretórios temporários e configurações de teste.

Teste exceções

Um exemplo pode documentar o traceback esperado. A pilha intermediária é normalmente ignorada; o tipo e a mensagem são comparados.

def dividir(a, b):
    """
    >>> dividir(10, 0)
    Traceback (most recent call last):
    ...
    ZeroDivisionError: division by zero
    """
    return a / b

Quando mensagens variam entre versões, use IGNORE_EXCEPTION_DETAIL com cuidado. Ainda é importante confirmar o tipo correto da exceção.

Normalize espaços

NORMALIZE_WHITESPACE considera sequências de espaços e quebras equivalentes.

>>> print(list(range(10)))  # doctest: +NORMALIZE_WHITESPACE
[0, 1, 2, 3, 4,
 5, 6, 7, 8, 9]

Não ative a opção globalmente para esconder formatação que faz parte do contrato. Aplique diretivas somente nos exemplos necessários.

Use ELLIPSIS com moderação

ELLIPSIS permite que ... corresponda a qualquer trecho.

>>> objeto
<MeuObjeto id=...>  # doctest: +ELLIPSIS

Uma elipse muito ampla pode aceitar uma saída errada. Mantenha partes estáveis antes e depois do marcador.

Linhas em branco

Uma linha vazia encerra o bloco de saída esperada. Para exigir uma linha em branco, escreva <BLANKLINE>.

>>> print("primeira\n\nterceira")
primeira
<BLANKLINE>
terceira

Essa regra frequentemente causa falhas ao copiar saídas multilinha. Use uma representação estável e simples.

Ordenação não determinística

Não compare diretamente conjuntos ou estruturas cuja ordem possa variar.

>>> sorted(obter_tags())
['api', 'python', 'teste']

Para floats, arredonde ou formate com precisão explícita. Não documente endereços de memória, timestamps atuais, UUIDs aleatórios ou caminhos temporários sem normalização.

Use __test__

O dicionário de módulo __test__ permite adicionar exemplos que não devem aparecer na ajuda principal.

__test__ = {
    "casos_extras": """
    >>> dobro(0)
    0
    """,
}

Os valores podem ser strings, funções ou classes. O finder examina docstrings dos objetos fornecidos.

Objetos examinados

testmod() procura no docstring do módulo, funções, classes, métodos e objetos encontrados em __test__. Objetos importados de outros módulos não são examinados automaticamente.

Para entender como documentação é extraída e exibida, veja pydoc no Python. Para listar funções e classes sem executar módulos, consulte pyclbr no Python.

Integre com unittest

DocTestSuite() transforma os exemplos de um módulo em uma suíte unittest.

import doctest
import unittest
import meu_modulo


def load_tests(loader, tests, pattern):
    tests.addTests(doctest.DocTestSuite(meu_modulo))
    return tests

if __name__ == "__main__":
    unittest.main()

DocFileSuite() faz o mesmo para arquivos textuais. Essa integração facilita descoberta, relatórios e execução junto com testes convencionais.

Prepare e limpe recursos

As suítes aceitam setUp e tearDown.

def preparar(teste):
    teste.globs["repositorio"] = RepositorioTemporario()


def limpar(teste):
    teste.globs["repositorio"].close()

suite = doctest.DocTestSuite(
    meu_modulo,
    setUp=preparar,
    tearDown=limpar,
)

Garanta limpeza mesmo quando um exemplo falha. Prefira tempfile e mocks para recursos externos.

FAIL_FAST e relatórios

A linha de comando aceita -f, equivalente a FAIL_FAST. Outras flags oferecem diff unificado, contextual ou por caracteres.

python -m doctest -v -f guia.txt

Durante desenvolvimento, falhar cedo acelera o ciclo. Em CI, executar todos os exemplos pode revelar mais regressões em uma única rodada.

Marque um exemplo como SKIP

>>> abrir_navegador()  # doctest: +SKIP

SKIP é útil quando o exemplo é puramente ilustrativo ou depende de recurso indisponível. Um número crescente de skips pode esconder documentação quebrada; revise-os regularmente.

Analise exemplos com APIs avançadas

DocTestParser extrai objetos Example de uma string.

from doctest import DocTestParser

texto = """
>>> 2 + 2
4
"""
exemplos = DocTestParser().get_examples(texto)
print(exemplos[0].source, exemplos[0].want)

DocTestFinder, DocTestRunner e OutputChecker permitem criar integrações customizadas. Use a API básica enquanto ela atender.

Segurança

O doctest executa o conteúdo encontrado. Não rode documentação recebida de usuários, pacotes desconhecidos ou repositórios não confiáveis no processo principal.

Use container ou processo isolado, usuário restrito, timeout, memória limitada, rede bloqueada e diretório temporário. Importar o módulo testado também pode executar código superior antes dos exemplos.

Erros de sintaxe e tracebacks

O guia de traceback no Python explica pilhas e formatação de exceções. Em doctest, mantenha apenas os detalhes relevantes para evitar dependência de caminhos e linhas.

Inspeção e documentação

inspect no Python ajuda ferramentas que extraem assinaturas e docstrings antes de construir suítes ou relatórios. Lembre que introspecção de objetos vivos exige importar o código.

Quando não usar doctest

  • Fluxos com muitas etapas e fixtures complexas.
  • Saídas grandes ou instáveis.
  • Testes de concorrência e tempo.
  • Integrações de rede ou banco real.
  • Propriedades com muitos casos.
  • Regras críticas que precisam de mensagens detalhadas.

Nesses casos, use unittest, pytest ou testes especializados e mantenha no doctest apenas exemplos de uso.

Boas práticas

  • Escreva exemplos curtos e determinísticos.
  • Teste comportamento público, não detalhes internos.
  • Ordene coleções antes de comparar.
  • Formate floats explicitamente.
  • Use diretivas localmente.
  • Evite elipses excessivas.
  • Integre os exemplos ao CI.
  • Isole documentação não confiável.

Conclusão

O doctest no Python mantém exemplos sincronizados com o código e transforma documentação em teste executável. Ele é excelente para APIs pequenas, tutoriais e regressões legíveis, desde que as saídas sejam estáveis.

Consulte a documentação oficial do doctest e a documentação do unittest.

Compartilhe:

Facebook
WhatsApp
Twitter
LinkedIn

Conteúdo do artigo

    Artigos relacionados

    Código Python e representação de frações numéricas
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    fractions.from_number: converta números em frações

    Aprenda fractions.from_number no Python para converter números em frações exatas, controlar precisão e evitar arredondamentos inesperados.

    Ler mais

    Tempo de leitura: 5 minutos
    09/10/2026
    Desenvolvedor configurando servidor HTTPS e certificado TLS com Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    HTTPSServer: crie servidor HTTPS local no Python

    Aprenda HTTPSServer no Python para servir HTTPS localmente, configurar certificados, usar threads e entender limites de segurança.

    Ler mais

    Tempo de leitura: 5 minutos
    08/10/2026
    Arquivos protegidos representando extração segura de TAR com Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    tarfile extraction_filter: extraia TAR com segurança

    Aprenda tarfile extraction_filter no Python para extrair arquivos TAR com validação, segurança e controle de caminhos.

    Ler mais

    Tempo de leitura: 6 minutos
    08/10/2026
    Código Python exibindo avisos controlados com catch_warnings
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    catch_warnings: capture warnings em testes Python

    Aprenda catch_warnings no Python para capturar, testar e controlar avisos com filtros específicos e segurança.

    Ler mais

    Tempo de leitura: 5 minutos
    07/10/2026
    Código Python representando referências persistentes do pickle
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    pickle persistent_id: serialize referências externas

    Aprenda pickle persistent_id no Python para serializar referências externas com IDs estáveis, validação, segurança e compatibilidade.

    Ler mais

    Tempo de leitura: 5 minutos
    07/10/2026
    Código binário representando buffers e memória no Python
    Python Avançado
    Foto de perfil de Leandro Hirt da Academify

    memoryview.count: conte valores sem copiar buffers

    Aprenda memoryview.count no Python para contar bytes e valores em buffers sem cópias, com formatos, limites e boas práticas.

    Ler mais

    Tempo de leitura: 6 minutos
    06/10/2026