Możesz zdefiniować assertNotRaises, ponownie wykorzystując około 90% oryginalnej implementacji assertRaisesw unittestmodule. Dzięki takiemu podejściu uzyskuje się assertNotRaisesmetodę, która oprócz odwróconego stanu awarii zachowuje się identycznie assertRaises.
TLDR i demo na żywo
Okazuje się, że dodanie assertNotRaisesmetody jest zaskakująco łatwe unittest.TestCase(napisanie tej odpowiedzi zajęło mi około 4 razy więcej czasu niż kodu). Oto demo na żywo assertNotRaisesmetody w akcji . Tylko jakassertRaises , można przejść wywoływalnym i args się assertNotRaises, czy można go używać w withoświadczeniu. Demo na żywo zawiera przypadki testowe, które pokazują, że assertNotRaisesdziała zgodnie z przeznaczeniem.
Detale
Realizacja assertRaiseswunittest jest dość skomplikowana, ale przy odrobinie sprytnej podklasy można zastąpić i odwrócić jej stan awarii.
assertRaisesjest krótką metodą, która w zasadzie tworzy instancję unittest.case._AssertRaisesContextklasy i zwraca ją (patrz jej definicja w unittest.casemodule). Możesz zdefiniować własną _AssertNotRaisesContextklasę, podklasując _AssertRaisesContexti zastępując jej __exit__metodę:
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
Zwykle klasy przypadków testowych są definiowane przez dziedziczenie TestCase. Jeśli zamiast tego dziedziczysz z podklasy 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
wszystkie twoje przypadki testowe będą teraz miały assertNotRaisesdostępną dla nich metodę.