Vous pouvez définir assertNotRaisesen réutilisant environ 90% de l'implémentation d'origine de assertRaisesdans le unittestmodule. Avec cette approche, vous vous retrouvez avec une assertNotRaisesmé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 assertNotRaisesmé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 assertNotRaisesméthode en action . Tout commeassertRaises , vous pouvez soit passer un appelable et des arguments à assertNotRaises, soit l'utiliser dans une withinstruction. La démo en direct comprend un cas de test qui démontre que cela assertNotRaisesfonctionne comme prévu.
Détails
L'implémentation de assertRaisesin unittestest assez compliquée, mais avec un peu de sous-classement intelligent, vous pouvez remplacer et inverser sa condition d'échec.
assertRaisesest une méthode courte qui crée simplement une instance de la unittest.case._AssertRaisesContextclasse et la renvoie (voir sa définition dans le unittest.casemodule). Vous pouvez définir votre propre _AssertNotRaisesContextclasse 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 assertNotRaisesméthode à leur disposition.