pytest.raises()
: Проверяет, что код внутри блока with
вызывает ожидаемое исключение.try...except
блоки в тестах: Позволяют перехватывать исключения и проверять их атрибуты (сообщение, тип и т.д.).assert
: Для проверки, что сообщение исключения соответствует ожидаемому значению.Тестирование обработки собственных исключений в Python - важная часть обеспечения надежности и предсказуемости кода. Вот несколько подходов, которые можно использовать:
assertRaises
контекстный менеджер: Это наиболее распространенный и рекомендуемый способ. Он позволяет ожидать, что определенный блок кода вызовет конкретное исключение.
import unittest
class MyCustomError(Exception):
pass
def my_function(x):
if x < 0:
raise MyCustomError("Значение должно быть положительным")
return x * 2
class TestMyFunction(unittest.TestCase):
def test_my_function_raises_error(self):
with self.assertRaises(MyCustomError) as context:
my_function(-1)
self.assertEqual(str(context.exception), "Значение должно быть положительным") # Проверка сообщения об ошибке
def test_my_function_works(self):
self.assertEqual(my_function(5), 10)
if __name__ == '__main__':
unittest.main()
В этом примере:
MyCustomError
- наше пользовательское исключение.assertRaises(MyCustomError)
- контекстный менеджер, который проверяет, что внутри блока with
будет выброшено исключение MyCustomError
.context.exception
позволяет получить доступ к экземпляру исключения, чтобы проверить его атрибуты, например, сообщение.assertRaisesRegex
: Похож на assertRaises
, но позволяет проверять, что сообщение об ошибке соответствует определенному регулярному выражению.
import unittest
import re
class MyCustomError(Exception):
pass
def my_function(x):
if x < 0:
raise MyCustomError(f"Неверное значение: {x}")
return x * 2
class TestMyFunction(unittest.TestCase):
def test_my_function_raises_error_with_regex(self):
with self.assertRaisesRegex(MyCustomError, r"Неверное значение: -1"):
my_function(-1)
Здесь проверяется, что сообщение об ошибке содержит строку "Неверное значение: -1".
try...except
внутри тестовой функции, но этот подход менее читабелен и может быть сложнее в поддержке.
import unittest
class MyCustomError(Exception):
pass
def my_function(x):
if x < 0:
raise MyCustomError("Значение должно быть положительным")
return x * 2
class TestMyFunction(unittest.TestCase):
def test_my_function_raises_error_try_except(self):
try:
my_function(-1)
self.fail("MyCustomError не был вызван") # Если исключение не было вызвано, тест должен провалиться
except MyCustomError as e:
self.assertEqual(str(e), "Значение должно быть положительным")
Этот подход менее предпочтителен, так как делает тест более многословным и сложным для понимания.
Дополнительные советы: