Ответ
Для принудительной генерации (вызова) исключения в Python используется оператор raise. Он немедленно прерывает нормальное выполнение кода и передает управление ближайшему обработчику except.
Это ключевой механизм для сигнализации об ошибках или нештатных ситуациях в коде.
Синтаксис:
raise ExceptionType("Сообщение об ошибке")
Пример использования в функции:
def get_user_by_id(user_id: int):
if not isinstance(user_id, int) or user_id <= 0:
# Генерируем исключение, если ID некорректен
raise ValueError("ID пользователя должен быть положительным целым числом")
# ... логика поиска пользователя в базе данных
return {"id": user_id, "name": "John Doe"}
Применение в негативном тестировании
В тестах raise используется для проверки того, что код корректно обрабатывает ошибочные входные данные. Лучшей практикой является использование контекстного менеджера pytest.raises.
Пример теста с pytest:
import pytest
def test_get_user_with_invalid_id():
# Проверяем, что вызов функции с user_id = -1
# действительно генерирует исключение ValueError
with pytest.raises(ValueError, match="ID пользователя должен быть"):
get_user_by_id(-1)
Этот тест успешно пройдет, только если внутри блока with будет сгенерировано исключение ValueError, текст которого соответствует регулярному выражению в match.
Ответ 18+ 🔞
Да ты посмотри, что за хуйня творится в коде иногда! Ну вот представь: летит твоя программа, как шаровая молния, и тут — бац! — на тебе, какая-то неожиданная ситуация, которую в лоб не предусмотрел. Что делать? Правильно, орать на весь мир, что всё пошло по пизде! Для этого в Python и есть оператор raise. Он как красная кнопка — жмёшь, и нормальная работа кода немедленно накрывается медным тазом, а управление летит прямиком к ближайшему паникёру, то есть обработчику except.
Как это выглядит, спросишь?
raise ExceptionType("Сообщение об ошибке")
Вот тебе живой пример, чтоб понятнее было:
def get_user_by_id(user_id: int):
if not isinstance(user_id, int) or user_id <= 0:
# А вот тут мы и взываем к богам, если ID — полная хуйня
raise ValueError("ID пользователя должен быть положительным целым числом")
# ... дальше идёт какая-то магия с базой данных
return {"id": user_id, "name": "John Doe"}
А зачем это в тестах, спросит пытливый ум?
А вот зачем, ёпта! Чтобы проверить, не сломается ли твой код, если в него сунуть какую-нибудь дичь. Это называется негативным тестированием. И лучший способ это сделать — использовать pytest.raises. Это как подсунуть коту сардельку и ждать, что он на неё среагирует.
Смотри, как это круто выглядит в тесте:
import pytest
def test_get_user_with_invalid_id():
# Сейчас мы специально вызовем функцию с откровенным говном (user_id = -1)
# и будем ждать, что она правильно взбесится и выкинет ValueError
with pytest.raises(ValueError, match="ID пользователя должен быть"):
get_user_by_id(-1)
И этот тест пройдёт на ура только в одном случае: если внутри этого блока with функция действительно взорвётся нужным исключением ValueError, да ещё и с текстом, который мы ожидаем. А если не взорвётся — ну, значит, код говнарый, не умеет ругаться на кривые данные. Вот и вся философия, в рот меня чих-пых!