Exception d'assertion Python
- Utilisation du gestionnaire de contexte pour intercepter l’exception d’assertion Python
- Utilisation d’arguments de mot-clé pour attraper l’exception d’assertion Python
Cet article amène à comprendre assert
comme une unité de test, pour tester que les fonctions peuvent lever des exceptions (erreurs détectées lors de l’exécution du code) sans nécessairement sortir de l’exécution. En d’autres termes, l’exception levée est encapsulée.
Ce test réussira si une exception est levée. Une erreur est levée si une exception différente de celle attendue est levée. Dans un cas où il n’y a aucune exception levée, le test échoue.
Utilisation du gestionnaire de contexte pour intercepter l’exception d’assertion Python
Semblable à la façon dont il permet l’allocation et la libération de ressources lorsque cela est nécessairement requis dans le concept python général, le contexte saisit ici l’objet d’exception réel qui est lancé pendant le test.
Il stocke cet attribut d’exception dans l’objet s’il est nécessaire d’effectuer un contrôle de performance supplémentaire sur l’exception déclenchée.
Pour tester qu’une fonction échoue ou réussit, qu’une exception soit levée ou non, nous utiliserons TestCase.assertRaises
du module unittest
.
Voyons un exemple pratique utilisant le gestionnaire de contexte.
import unittest
class TestCase(unittest.TestCase):
def test_nameerror(self):
with self.assertRaises(Exception):
100 * (someNumber / 5)
if __name__ == "__main__":
unittest.main()
Production:
.
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
Dans l’exemple de code, le test réussit car nous nous attendons à ce qu’une exception soit levée. Nous divisons 5 par une variable indéfinie someNumber
. Par conséquent, la fonction lève une exception NameError
. Par conséquent, notre test réussit comme indiqué par le .
dans la première ligne de la sortie.
Voyons un exemple où le test échoue lorsqu’une exception n’est pas levée.
import unittest
class TestCase(unittest.TestCase):
def test_nameerror(self):
with self.assertRaises(Exception):
someNumber = 10
100 * (someNumber / 5)
if __name__ == "__main__":
unittest.main()
Production:
F
======================================================================
FAIL: test_nameerror (__main__.MyTestCase)
----------------------------------------------------------------------
Traceback (most recent call last): File "c:\Users\Neema\Desktop\Article Requirement Spec and Example
Articles\Article Requirement Spec
and Example Articles\fah.py", line 106, in test_nameerror
100 * (someNumber/5)
AssertionError: Exception not raised
----------------------------------------------------------------------
Ran 1 test in 0.002s
FAILED (failures=1)
Dans cet exemple de code, nous définissons une valeur pour someNumber
puis nous effectuons l’expression arithmétique avec.
La sortie nous montre que le test échoue comme prévu. Nous ne nous attendons pas à ce qu’une exception NameError
soit levée cette fois car une valeur définie pour someNumber
existe.
Nous pouvons également implémenter le gestionnaire de contexte en utilisant des exceptions définies par l’utilisateur comme dans l’exemple suivant.
import unittest
def user_function():
raise Exception("A user-defined exception")
class MyTestCase(unittest.TestCase):
def test_userexception(self):
with self.assertRaises(Exception) as context:
user_function()
self.assertTrue("A user-defined exception" in str(context.exception))
if __name__ == "__main__":
unittest.main()
Production:
.
----------------------------------------------------------------------
Ran 1 test in 0.006s
OK
N’oubliez pas d’utiliser
str
pour entourer lecontext.exception
pour éviter d’obtenir une TypeError.
Nous introduisons assertTrue
, une bibliothèque unittest
qui compare une valeur de test avec true dans les tests unitaires.
Vous pouvez également choisir d’utiliser assertIn
au lieu de assertTrue.
Exemple:
import unittest
def user_function():
raise Exception("A use defined exception")
class MyTestCase(unittest.TestCase):
def test_userexception(self):
with self.assertRaises(Exception) as context:
user_function()
self.assertIn("A use defined exception", str(context.exception))
if __name__ == "__main__":
unittest.main()
Nous voyons la même sortie où les tests réussis seront produits.
Utilisation d’arguments de mot-clé pour attraper l’exception d’assertion Python
Contrairement au gestionnaire de contexte, où l’on ne passe que l’exception à assertRaises()
, on passe également l’appel de fonction et les paramètres de la fonction comme arguments mot-clé pour évoquer l’exception.
Syntaxe
assertRaises(exception, function, *args, **keywords)
Exemple:
import unittest
class MyTestCase(unittest.TestCase):
def test_division_by_error(self):
import operator
self.assertRaises(ZeroDivisionError, operator.floordiv, 55, 0)
if __name__ == "__main__":
unittest.main()
Production:
.
----------------------------------------------------------------------
Ran 1 test in 0.002s
OK
L’exemple de code ci-dessus utilisait assertRaises()
avec des arguments de mot-clé. Nous lui avons passé l’exception ZeroDivisionError
attendue après avoir tenté de diviser un nombre par zéro. Nous avons importé la fonction opérateur utilisée avec la fonction opérateur floordiv
comme deuxième argument. Les valeurs des paramètres ici sont les troisièmes paramètres ; 55 pour diviser par 0.
La dernière application de assert est lorsque nous passons une exception différente de celle attendue à assertRaises(). Une erreur est générée à la place.
En utilisant le même exemple de code que nous venons d’utiliser ci-dessus, implémentons ceci.
import unittest
class MyTestCase(unittest.TestCase):
def test_division_by_error(self):
import operator
self.assertRaises(TypeError, operator.floordiv, 55, 0)
if __name__ == "__main__":
unittest.main()
Production:
E
======================================================================
ERROR: test_division_by_error (__main__.MyTestCase)
----------------------------------------------------------------------
Traceback (most recent call last): File "c:\Users\Neema\Desktop\Article Requirement Spec and Example
Articles\user.py", line 16, in test_division_by_error
self.assertRaises(TypeError, operator.floordiv, 55, 0)
File "C:\Users\Neema\AppData\Local\Programs\Python\Python39\lib\unittest\case.py", line 733, in assertRaises
return context.handle('assertRaises', args, kwargs)
File "C:\Users\Neema\AppData\Local\Programs\Python\Python39\lib\unittest\case.py", line 201, in handle
callable_obj(*args, **kwargs)
ZeroDivisionError: integer division or modulo by zero
----------------------------------------------------------------------
Ran 1 test in 0.031s
FAILED (errors=1)
À partir de la sortie, une trace d’erreur est produite. Nous attendons une exception ZeroDivisionError lorsque nous divisons un nombre par zéro. Au lieu de cela, nous passons une exception TypeError appliquée lors de l’exécution d’une opération arithmétique entre différents types de données, disons une chaîne et un entier.