Ви можете визначити assertNotRaisesшляхом повторного використання близько 90% від первісної реалізації assertRaisesв unittestмодулі. При такому підході ви закінчуєте assertNotRaisesметод, який, окрім його зворотного стану відмови, поводиться однаково assertRaises.
TLDR та демо-версія
Додавати assertNotRaisesметод до напрочуд легко unittest.TestCase(мені знадобилося приблизно 4 рази більше часу, щоб написати цю відповідь, як це робив код). Ось жива демонстрація assertNotRaisesметоду в дії . Так само, якassertRaises ви можете або передати позивний і аргумент до assertNotRaises, або ви можете використовувати його у withзаяві. Демонстраційна демонстрація включає тестові приклади, які демонструють, що assertNotRaisesпрацює за призначенням.
Деталі
Реалізація assertRaisesв unittestдосить складна, але, маючи трохи розумного підкласингу, ви можете переосмислити та змінити умови його відмови.
assertRaisesце короткий метод, який в основному просто створює екземпляр unittest.case._AssertRaisesContextкласу і повертає його (див. його визначення в unittest.caseмодулі). Ви можете визначити свій власний _AssertNotRaisesContextклас, підкласифікувавши _AssertRaisesContextта змінивши його __exit__метод:
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
Зазвичай ви визначаєте класи тестових випадків, успадковуючи їх TestCase. Якщо ви замість цього успадковуєте підклас 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
у всіх ваших тестових випадках тепер буде assertNotRaisesдоступний метод.