Tests de programmes
Un programme doit être effectuer le travail pour lequel il a été conçu. Il faut s’assurer que l’algorithme renvoie le résultat attendu en fonction des données qu’il doit traiter.
Idéalement, il faudrait systématiquement établir une preuve de correction (ou preuve de validité).
Les méthodes de preuve étant parfois très complexes, on se contente souvent de tester le code à partir d’entrées dont le résultats est connu.
Tests unitaires
On qualifie un test d’unitaire quand il s’applique à une unique fonction d’un programme. Il faut par conséquent réaliser autant de tests unitaires qu’un programme comporte de fonctions.
Un test unitaire doit envisager le plus de cas possible.
Les tests unitaires d’un programme doivent être réalisés le plus fréquemment possible, afin d’éviter d’éventuels problèmes de régression (apparition de bugs lors de la modification du code).
Assertions
Une assertion est une proposition, de forme affirmative ou négative, qu’on avance et qu’on donne comme vraie (Larousse).
En Python, un mécanisme d’assertion est prévu grâce à l’instruction assert
. Les assertions permettent de définir des préconditions pour un programme, c’est à dire les conditions qui doivent être satisfaites sur les paramètres et l’état global du programme, avant son exécution.
On réalise des assertions de la manière suivante :
assert condition [, message]
- si
condition
est vraie, le programme continue, - si
condition
est fausse, le programme est interrompu. En réalité, une exceptionAssertionError
est levée, mais il est toujours possible de l’intercepter à l’aide d’une structuretry: .. Except: ...
, mais cela présente peu d’intérêt !
si message est donné (facultatif), il est alors affiché à
Exemples :
>>> assert 1 == 2 Traceback (most recent call last): File "<console>", line 1, in <module> AssertionError
avec un message
>>> assert 1 == 2, "Faux !" Traceback (most recent call last): File "<console>", line 1, in <module> AssertionError: Faux !
Il est important de noter qu’une assertion fausse signifie la présence d’un bug !
Il ne faut jamais utiliser d’assertion pour valider des données : les assertions pouvant être désactivée globalement au niveau de l’interpréteur Python, cela pourrait causer des bugs inattendus, voire de créer des failles de sécurité !
La technique des assertions est très pertinente en phase de développement, et pour les développeurs.
Module doctest
Le module doctext
permet d’utiliser les docstrings pour réaliser des tests unitaires.
Après avoir fait :
import doctest
on peut ajouter des lignes « spéciales » à la docstring d’une fonction :
def maFonction(n): """ Documentation de la fonction maFonction ... Tests unitaires : >>> maFonction(1) 8 >>> maFonction(2) 15 """ return n * 8
fonction qui pourra alors être validée grâce à l’unique instruction :
doctest.testmod()
En cas d’échec à un ou plusieurs tests unitaires, le message suivant apparait :
Failed example: maFonction(2) Expected: 15 Got: 16
En principe, les tests unitaires devant être réalisés en phase de développement seulement, on place les instructions de test … dans le bloc de test du module en développement !
if __name__ == "__main__": import doctest doctest.testmod()
Module pytest
pytest est une bibliothèque qui permet d’écrire facilement de petits tests, bien lisibles et pouvant évoluer pour prendre en charge des tests fonctionnels complexes pour les applications et les bibliothèques.