Framework UnitTest - Doctest

La distribuzione standard di Python contiene il modulo "Doctest". La funzionalità di questo modulo rende possibile la ricerca di parti di testo che sembrano sessioni interattive di Python ed esegue queste sessioni per vedere se funzionano esattamente come mostrato.

Doctest può essere molto utile nei seguenti scenari:

  • Per controllare che le docstring di un modulo siano aggiornate verificando che tutti gli esempi interattivi funzionino ancora come documentato.

  • Per eseguire test di regressione verificando che gli esempi interattivi da un file di test o da un oggetto di test funzionino come previsto.

  • Scrivere documentazione tutorial per un pacchetto, liberamente illustrata con esempi di input-output

In Python, una "docstring" è una stringa letterale che appare come la prima espressione in una classe, funzione o modulo. Viene ignorato quando la suite viene eseguita, ma viene riconosciuto dal compilatore e inserito nel file__doc__attributo della classe, funzione o modulo che lo racchiude. Poiché è disponibile tramite introspezione, è il luogo canonico per la documentazione dell'oggetto.

È una pratica abituale inserire un esempio di utilizzo di diverse parti del codice Python all'interno della docstring. Il modulo doctest permette di verificare che queste docstring siano aggiornate con le revisioni intermittenti nel codice.

Nel codice seguente, una funzione fattoriale è definita intervallata da un utilizzo di esempio. Per verificare se l'uso dell'esempio è corretto, chiama la funzione testmod () nel modulo 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()

Immettere e salvare lo script sopra come FactDocTest.py e provare a eseguire questo script dalla riga di comando.

Python FactDocTest.py

Nessun output verrà mostrato a meno che l'esempio non fallisca. Ora, cambia la riga di comando come segue:

Python FactDocTest.py –v

La console ora mostrerà il seguente output:

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, d'altra parte, il codice della funzione factorial () non fornisce il risultato atteso in docstring, verrà visualizzato il risultato del fallimento. Ad esempio, cambia f = 2 al posto di f = 1 nello script sopra ed esegui di nuovo il doctest. Il risultato sarà il seguente:

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: controllo degli esempi in un file di testo

Un'altra semplice applicazione di doctest è testare esempi interattivi in ​​un file di testo. Questo può essere fatto con la funzione testfile ().

Il testo seguente è memorizzato in un file di testo denominato "esempio.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

Il contenuto del file viene trattato come docstring. Per verificare gli esempi nel file di testo, utilizzare la funzione testfile () del modulo 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")
  • Come con testmod (), testfile () non mostrerà nulla a meno che un esempio non fallisca. Se un esempio non riesce, gli esempi e le cause degli errori vengono stampati sulla console, utilizzando lo stesso formato di testmod ().

  • Nella maggior parte dei casi un copia e incolla di una sessione di console interattiva funziona bene, ma doctest non sta cercando di eseguire un'esatta emulazione di una specifica shell Python.

  • Qualsiasi output atteso deve seguire immediatamente la riga finale ">>>" o "..." contenente il codice e l'output previsto (se presente) si estende alla riga successiva ">>>" o di tutti gli spazi.

  • L'output atteso non può contenere una riga di tutti gli spazi, poiché tale riga viene presa per segnalare la fine dell'output atteso. Se l'output previsto contiene una riga vuota, inserire <BLANKLINE> nell'esempio del doctest ogni posizione è prevista una riga vuota.