Cadre UnitTest - Doctest

La distribution standard de Python contient le module «Doctest». La fonctionnalité de ce module permet de rechercher des morceaux de texte qui ressemblent à des sessions Python interactives, et exécute ces sessions pour voir si elles fonctionnent exactement comme indiqué.

Doctest peut être très utile dans les scénarios suivants -

  • Pour vérifier que les docstrings d'un module sont à jour en vérifiant que tous les exemples interactifs fonctionnent toujours comme documenté.

  • Pour effectuer des tests de régression en vérifiant que les exemples interactifs d'un fichier de test ou d'un objet de test fonctionnent comme prévu.

  • Pour rédiger la documentation du didacticiel pour un package, largement illustrée par des exemples d'entrée-sortie

En Python, une «docstring» est une chaîne littérale qui apparaît comme la première expression dans une classe, une fonction ou un module. Il est ignoré lorsque la suite est exécutée, mais il est reconnu par le compilateur et placé dans le__doc__attribut de la classe, de la fonction ou du module englobant. Puisqu'il est disponible via l'introspection, c'est le lieu canonique de documentation de l'objet.

Il est courant de mettre des exemples d'utilisation de différentes parties du code Python dans la docstring. Le module doctest permet de vérifier que ces docstrings sont à jour avec les révisions intermittentes du code.

Dans le code suivant, une fonction factorielle est définie entrecoupée d'exemples d'utilisation. Afin de vérifier si l'utilisation de l'exemple est correcte, appelez la fonction testmod () dans le module 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()

Entrez et enregistrez le script ci-dessus sous FactDocTest.py et essayez d'exécuter ce script à partir de la ligne de commande.

Python FactDocTest.py

Aucune sortie ne sera affichée sauf si l'exemple échoue. Maintenant, changez la ligne de commande comme suit -

Python FactDocTest.py –v

La console affichera maintenant la sortie suivante -

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.

Si, par contre, le code de la fonction factorial () ne donne pas le résultat attendu dans docstring, le résultat de l'échec sera affiché. Par exemple, changez f = 2 à la place de f = 1 dans le script ci-dessus et exécutez à nouveau le doctest. Le résultat sera le suivant -

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: vérification d'exemples dans un fichier texte

Une autre application simple de doctest consiste à tester des exemples interactifs dans un fichier texte. Cela peut être fait avec la fonction testfile ().

Le texte suivant est stocké dans un fichier texte nommé «exemple.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

Le contenu du fichier est traité comme docstring. Afin de vérifier les exemples dans le fichier texte, utilisez la fonction testfile () du module 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")
  • Comme avec testmod (), testfile () n'affichera rien sauf si un exemple échoue. Si un exemple échoue, alors le (s) exemple (s) défaillant (s) et la ou les causes de l'échec (s) sont imprimés sur la console, en utilisant le même format que testmod ().

  • Dans la plupart des cas, un copier-coller d'une session de console interactive fonctionne bien, mais doctest n'essaie pas de faire une émulation exacte d'un shell Python spécifique.

  • Toute sortie attendue doit immédiatement suivre la ligne finale '>>>' ou '...' contenant le code, et la sortie attendue (le cas échéant) s'étend à la ligne suivante '>>>' ou entièrement blanche.

  • La sortie attendue ne peut pas contenir une ligne entièrement blanche, car une telle ligne est prise pour signaler la fin de la sortie attendue. Si la sortie attendue contient une ligne vide, mettez <BLANKLINE> dans votre exemple de doctest à chaque endroit où une ligne vide est attendue.