Estrutura UnitTest - Doctest

A distribuição padrão do Python contém o módulo 'Doctest'. A funcionalidade deste módulo torna possível procurar por pedaços de texto que se parecem com sessões Python interativas e executa essas sessões para ver se elas funcionam exatamente como mostrado.

O Doctest pode ser muito útil nos seguintes cenários -

  • Para verificar se as docstrings de um módulo estão atualizadas, verificando se todos os exemplos interativos ainda funcionam conforme documentado.

  • Para realizar o teste de regressão, verificando se os exemplos interativos de um arquivo de teste ou um objeto de teste funcionam conforme o esperado.

  • Para escrever documentação de tutorial para um pacote, amplamente ilustrado com exemplos de entrada-saída

Em Python, uma 'docstring' é uma string literal que aparece como a primeira expressão em uma classe, função ou módulo. Ele é ignorado quando o pacote é executado, mas é reconhecido pelo compilador e colocado no__doc__atributo da classe, função ou módulo envolvente. Por estar disponível via introspecção, é o local canônico para a documentação do objeto.

É uma prática comum colocar o uso de exemplo de diferentes partes do código Python dentro da docstring. O módulo doctest permite verificar se essas docstrings estão atualizadas com as revisões intermitentes do código.

No código a seguir, uma função fatorial é definida intercalada com o uso de exemplo. Para verificar se o uso do exemplo está correto, chame a função testmod () no módulo doctest.

"""
This is the "example" module.

The example module supplies one function, factorial(). For example,

>>> factorial(5)
120
"""

def factorial(x):
   """Return the factorial of n, an exact integer >= 0.
   >>> factorial(-1)
   Traceback (most recent call last):
      ...
   ValueError: x must be >= 0
   """
   
   if not x >= 0:
      raise ValueError("x must be >= 0")
   f = 1
   for i in range(1,x+1):
      f = f*i
   return f
   
if __name__ == "__main__":
   import doctest
   doctest.testmod()

Digite e salve o script acima como FactDocTest.py e tente executar este script a partir da linha de comando.

Python FactDocTest.py

Nenhuma saída será mostrada a menos que o exemplo falhe. Agora, altere a linha de comando para o seguinte -

Python FactDocTest.py –v

O console agora mostrará a seguinte saída -

C:\Python27>python FactDocTest.py -v
Trying:
   factorial(5)
Expecting:
   120
ok
Trying:
   factorial(-1)
Expecting:
   Traceback (most recent call last):
      ...
   ValueError: x must be >= 0
ok
2 items passed all tests:
   1 tests in __main__
   1 tests in __main__.factorial
2 tests in 2 items.
2 passed and 0 failed.
Test passed.

Se, por outro lado, o código da função factorial () não der o resultado esperado em docstring, o resultado da falha será exibido. Por exemplo, altere f = 2 no lugar de f = 1 no script acima e execute o doctest novamente. O resultado será o seguinte -

Trying:
   factorial(5)
Expecting:
   120
**********************************************************************
File "docfacttest.py", line 6, in __main__
Failed example:
factorial(5)
Expected:
   120
Got:
   240
Trying:
   factorial(-1)
Expecting:
   Traceback (most recent call last):
      ...
   ValueError: x must be >= 0
ok
1 items passed all tests:
   1 tests in __main__.factorial
**********************************************************************
1 items had failures:
   1 of 1 in __main__
2 tests in 2 items.
1 passed and 1 failed.
***Test Failed*** 1 failures.

Doctest: Verificando exemplos em um arquivo de texto

Outra aplicação simples do doctest é testar exemplos interativos em um arquivo de texto. Isso pode ser feito com a função testfile ().

O texto a seguir é armazenado em um arquivo de texto denominado 'example.txt'.

Using ''factorial''
-------------------
This is an example text file in reStructuredText format. First import
''factorial'' from the ''example'' module:
   >>> from example import factorial
Now use it:
   >>> factorial(5)
   120

O conteúdo do arquivo é tratado como docstring. Para verificar os exemplos no arquivo de texto, use a função testfile () do módulo doctest.

def factorial(x):
   if not x >= 0:
      raise ValueError("x must be >= 0")
   f = 1
   for i in range(1,x+1):
      f = f*i
   return f
   
if __name__ == "__main__":
   import doctest
   doctest.testfile("example.txt")
  • Como acontece com testmod (), testfile () não exibirá nada, a menos que um exemplo falhe. Se um exemplo falhar, o (s) exemplo (s) com falha e a (s) causa (s) da (s) falha (s) são impressos no console, usando o mesmo formato de testmod ().

  • Na maioria dos casos, copiar e colar uma sessão de console interativo funciona bem, mas doctest não está tentando fazer uma emulação exata de qualquer shell Python específico.

  • Qualquer saída esperada deve seguir imediatamente a linha final '>>>' ou '...' que contém o código, e a saída esperada (se houver) se estende até a próxima linha '>>>' ou com todos os espaços em branco.

  • A saída esperada não pode conter uma linha totalmente em branco, uma vez que tal linha é usada para sinalizar o fim da saída esperada. Se a saída esperada contiver uma linha em branco, coloque <BLANKLINE> em seu exemplo de doctest, cada lugar em que uma linha em branco é esperada.