Como escrever e usar doctest para escrever código de teste em docstrings em Python.

O negócio

Python vem com um módulo padrão de teste docstring que testa o conteúdo de uma docstring, tornando fácil escrever exemplos de entrada e saída na docstring e tornando a documentação mais fácil de compreender.

A seguinte informação é fornecida aqui.

  • Um exemplo simples de teste com doctest
    • Se não houver erro
    • Se houver um erro
  • Controlar os resultados de saída por opções e argumentos
    • -vOpção
    • verboseargumento (por exemplo, função, programa, programa)
  • Executar o módulo doctest a partir da linha de comando
  • Testes de escrita num ficheiro de texto externo
    • Como escrever um ficheiro de texto
    • Chamado a partir de ficheiro py
    • Executar directamente um ficheiro de texto

Um exemplo simples de teste com doctest

Um docstring é um cordel encerrado num dos seguintes: (1) o nome da função a ser testada, (2) o nome da função a ser testada, e (3) o valor de saída esperado no modo interactivo Python.

  • """
  • '''

Se não houver erro

Certificar-se de que o código está correcto na função e no conteúdo do docstring.

def add(a, b):
    '''
    >>> add(1, 2)
    3
    >>> add(5, 10)
    15
    '''

    return a + b


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

Execute este ficheiro.

$ python3 doctest_example.py

Se não houver erros, nada será produzido.

if __name__ == '__main__'Isto significa “executar o processamento subsequente apenas quando o ficheiro de script correspondente for executado a partir da linha de comando”.

Se houver um erro

Se criar e executar o seguinte código errado, será emitido um erro.

def add(a, b):
    '''
    >>> add(1, 2)
    3
    >>> add(5, 10)
    10
    '''

    return a * b


if __name__ == '__main__':
    import doctest
    doctest.testmod()
$ python3 doctest_example_error.py
**********************************************************************
File "doctest_example_error.py", line 3, in __main__.add
Failed example:
    add(1, 2)
Expected:
    3
Got:
    2
**********************************************************************
File "doctest_example_error.py", line 5, in __main__.add
Failed example:
    add(5, 10)
Expected:
    10
Got:
    50
**********************************************************************
1 items had failures:
   2 of   2 in __main__.add
***Test Failed*** 2 failures.

É mostrado como se segue.

Valores de saída esperados escritos em doctest.Expected
Valor de saída realGot

Controlar os resultados de saída por opções e argumentos

-vOpção

Se quiser que os resultados de saída sejam exibidos mesmo quando não há erros, execute o comando com a opção -v na linha de comando.

$ python3 doctest_example.py -v
Trying:
    add(1, 2)
Expecting:
    3
ok
Trying:
    add(5, 10)
Expecting:
    15
ok
1 items had no tests:
    __main__
1 items passed all tests:
   2 tests in __main__.add
2 tests in 2 items.
2 passed and 0 failed.
Test passed.

verboseargumento (por exemplo, função, programa, programa)

Se quiser mostrar sempre os resultados de saída, especificar o argumento verbose=True no doctest.testmod() no ficheiro py.

if __name__ == '__main__':
    import doctest
    doctest.testmod(verbose=True)

Os resultados de saída serão sempre apresentados sem a opção -v em tempo de execução.

$ python3 doctest_example_verbose.py
Trying:
    add(1, 2)
Expecting:
    3
ok
Trying:
    add(5, 10)
Expecting:
    15
ok
1 items had no tests:
    __main__
1 items passed all tests:
   2 tests in __main__.add
2 tests in 2 items.
2 passed and 0 failed.
Test passed.

Executar o módulo doctest a partir da linha de comando

if __name__ == '__main__'Se quiser fazer algo mais nele, pode executar o módulo doctest directamente da linha de comando sem chamar doctest.testmod() no ficheiro py.

Por exemplo, nos seguintes casos

def add(a, b):
    '''
    >>> add(1, 2)
    3
    >>> add(5, 10)
    15
    '''

    return a + b


if __name__ == '__main__':
    import sys
    result = add(int(sys.argv[1]), int(sys.argv[2]))
    print(result)

Pode receber argumentos de linha de comando e executar o processo como habitualmente.

$ python3 doctest_example_without_import.py 3 4
7

Se correr doctest como um guião com a opção -m, o teste será executado contra a função em que o doctest é escrito. Se quiser exibir os resultados de saída, adicione -v como antes.

$ python3 -m doctest doctest_example_without_import.py

$ python3 -m doctest -v doctest_example_without_import.py
Trying:
    add(1, 2)
Expecting:
    3
ok
Trying:
    add(5, 10)
Expecting:
    15
ok
1 items had no tests:
    doctest_example_without_import
1 items passed all tests:
   2 tests in doctest_example_without_import.add
2 tests in 2 items.
2 passed and 0 failed.
Test passed.

Testes de escrita num ficheiro de texto externo

Também pode escrever o código de teste num ficheiro de texto externo em vez de o escrever no docstring.

Como escrever um ficheiro de texto

Escrever em modo interactivo Python, tal como descrito em docstring. É necessário importar as funções a serem utilizadas.

Se quiser colocar o ficheiro de texto no mesmo directório que o ficheiro .py a ser testado, basta importá-lo como se segue.

>>> from doctest_example import add
>>> add(1, 2)
3
>>> add(5, 10)
15

Chamado a partir de ficheiro py

Chamar doctest.testfile() num outro ficheiro .py para testes.

Especificar o caminho do ficheiro de texto onde o código do teste é escrito como o argumento de doctest.testfile().

import doctest
doctest.testfile('doctest_text.txt')

Executar este ficheiro py.

$ python3 doctest_example_testfile.py -v
Trying:
    from doctest_example import add
Expecting nothing
ok
Trying:
    add(1, 2)
Expecting:
    3
ok
Trying:
    add(5, 10)
Expecting:
    15
ok
1 items passed all tests:
   3 tests in doctest_text.txt
3 tests in 1 items.
3 passed and 0 failed.
Test passed.

Executar directamente um ficheiro de texto

Mesmo que não tenha o ficheiro py, pode ler o ficheiro de texto directamente a partir da linha de comando e executar os testes.

Executar o comando Python com a opção -m para executar doctest como um guião. Pode especificar o caminho do ficheiro de texto como um argumento de linha de comando.

$ python3 -m doctest -v doctest_text.txt
Trying:
    from doctest_example import add
Expecting nothing
ok
Trying:
    add(1, 2)
Expecting:
    3
ok
Trying:
    add(5, 10)
Expecting:
    15
ok
1 items passed all tests:
   3 tests in doctest_text.txt
3 tests in 1 items.
3 passed and 0 failed.
Test passed.
Copied title and URL