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), "Значение должно быть положительным")
      Этот подход менее предпочтителен, так как делает тест более многословным и сложным для понимания.
Дополнительные советы: