Vous pouvez définir assertNotRaises
en réutilisant environ 90% de l'implémentation d'origine de assertRaises
dans le unittest
module. Avec cette approche, vous vous retrouvez avec une assertNotRaises
méthode qui, à part sa condition de défaillance inversée, se comporte de manière identique à assertRaises
.
TLDR et démo en direct
Il s'avère étonnamment facile d'ajouter une assertNotRaises
méthode unittest.TestCase
(il m'a fallu environ 4 fois plus de temps pour écrire cette réponse que pour le code). Voici une démonstration en direct de la assertNotRaises
méthode en action . Tout commeassertRaises
, vous pouvez soit passer un appelable et des arguments à assertNotRaises
, soit l'utiliser dans une with
instruction. La démo en direct comprend un cas de test qui démontre que cela assertNotRaises
fonctionne comme prévu.
Détails
L'implémentation de assertRaises
in unittest
est assez compliquée, mais avec un peu de sous-classement intelligent, vous pouvez remplacer et inverser sa condition d'échec.
assertRaises
est une méthode courte qui crée simplement une instance de la unittest.case._AssertRaisesContext
classe et la renvoie (voir sa définition dans le unittest.case
module). Vous pouvez définir votre propre _AssertNotRaisesContext
classe en sous _AssertRaisesContext
-classant et en remplaçant sa __exit__
méthode:
import traceback
from unittest.case import _AssertRaisesContext
class _AssertNotRaisesContext(_AssertRaisesContext):
def __exit__(self, exc_type, exc_value, tb):
if exc_type is not None:
self.exception = exc_value.with_traceback(None)
try:
exc_name = self.expected.__name__
except AttributeError:
exc_name = str(self.expected)
if self.obj_name:
self._raiseFailure("{} raised by {}".format(exc_name,
self.obj_name))
else:
self._raiseFailure("{} raised".format(exc_name))
else:
traceback.clear_frames(tb)
return True
Normalement, vous définissez des classes de cas de test en les faisant hériter de TestCase
. Si vous héritez plutôt d'une sous-classe MyTestCase
:
class MyTestCase(unittest.TestCase):
def assertNotRaises(self, expected_exception, *args, **kwargs):
context = _AssertNotRaisesContext(expected_exception, self)
try:
return context.handle('assertNotRaises', args, kwargs)
finally:
context = None
tous vos cas de test auront désormais la assertNotRaises
méthode à leur disposition.