Unittest.TestCase.assertRaises: примеры (PYTHON)
unittest.TestCase.assertRaises(exception, callable, args, kwargs, msg): NoneОсновы функции assertRaises
Метод assertRaises() является частью фреймворка unittest и предназначен для проверки возникновения исключений в тестируемом коде. Он используется в модульных тестах для подтверждения, что определенный фрагмент кода генерирует ожидаемый тип исключения при выполнении.
Сигнатура метода: assertRaises(expected_exception, callable, *args, **kwargs)
Параметры:
- expected_exception - класс исключения или кортеж классов исключений, который ожидается при вызове.
- callable - вызываемый объект (функция, метод, класс), который проверяется на выброс исключения.
- *args - позиционные аргументы, передаваемые в вызываемый объект.
- **kwargs - именованные аргументы, передаваемые в вызываемый объект.
- msg - необязательное сообщение, выводимое при провале теста (доступен как keyword-only аргумент в контекстном менеджере).
Метод возвращает контекстный менеджер при использовании с оператором with, что позволяет проверить исключение от блока кода. Если исключение ожидаемого типа возникает, тест проходит успешно. При отсутствии исключения или возникновении исключения другого типа тест завершается ошибкой.
Базовые примеры использования
Проверка возникновения исключения при делении на ноль:
import unittest
def divide(a, b):
return a / b
class TestExample(unittest.TestCase):
def test_divide_by_zero(self):
self.assertRaises(ZeroDivisionError, divide, 10, 0)
if __name__ == '__main__':
unittest.main(). ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
Использование в качестве контекстного менеджера:
class TestExample(unittest.TestCase):
def test_with_context_manager(self):
with self.assertRaises(ValueError):
int('не число')
def test_with_context_and_message(self):
with self.assertRaises(TypeError, msg='Ожидалась ошибка типа'):
'строка' + 123.. ---------------------------------------------------------------------- Ran 2 tests in 0.001s OK
Похожие функции в Python
assertRaisesRegex - проверяет соответствие текста исключения регулярному выражению. Полезен, когда важно содержание сообщения об ошибке.
class TestAlternatives(unittest.TestCase):
def test_regex(self):
with self.assertRaisesRegex(ValueError, 'invalid literal'):
int('abc')pytest.raises - аналог в фреймворке pytest с более гибким синтаксисом. Может использоваться как контекстный менеджер или декоратор.
import pytest
def test_pytest_raises():
with pytest.raises(IndexError):
[][0]unittest.TestCase.assertWarns - проверяет возникновение предупреждений вместо исключений.
Выбор между методами зависит от фреймворка тестирования. В рамках unittest предпочтительнее использовать assertRaises. Для проверки точного текста исключения подходит assertRaisesRegex.
Аналоги в других языках программирования
JavaScript (Jest): используется метод toThrow.
test('деление на ноль', () => {
expect(() => 1/0).not.toThrow();
expect(() => { throw new Error('ошибка') }).toThrow();
});Java (JUnit 5): метод assertThrows возвращает исключение для дальнейшей проверки.
@Test
void testException() {
Exception exception = assertThrows(
ArithmeticException.class,
() -> { int a = 1 / 0; }
);
assertEquals("/ by zero", exception.getMessage());
}C# (NUnit): используется конструкция Assert.Throws.
[Test]
public void TestException()
{
Assert.Throws(() =>
{
int x = 10 / 0;
});
} PHP (PHPUnit): метод expectException.
public function testException(): void
{
$this->expectException(InvalidArgumentException::class);
// код, вызывающий исключение
}Основное отличие Python-реализации - поддержка как прямого вызова, так и контекстного менеджера. В других языках обычно используется один подход.
Типичные ошибки
Неправильная передача вызываемого объекта с аргументами:
class TestErrors(unittest.TestCase):
def test_wrong_call(self):
# Ошибка: исключение не возникает, так как функция вызывается сразу
self.assertRaises(ValueError, int('abc')) # Неправильно
def test_correct_call(self):
# Правильно: функция передается без вызова
self.assertRaises(ValueError, int, 'abc') # ПравильноE ====================================================================== ERROR: test_wrong_call (__main__.TestErrors) ---------------------------------------------------------------------- ValueError: invalid literal for int() with base 10: 'abc' ---------------------------------------------------------------------- Ran 1 test in 0.001s FAILED (errors=1)
Проверка не того типа исключения:
class TestErrors(unittest.TestCase):
def test_wrong_exception(self):
with self.assertRaises(TypeError): # Ожидается TypeError
int('abc') # Фактически возникает ValueErrorF ====================================================================== FAIL: test_wrong_exception (__main__.TestErrors) ---------------------------------------------------------------------- AssertionError: TypeError not raised ---------------------------------------------------------------------- Ran 1 test in 0.001s FAILED (failures=1)
История изменений
В Python 3.2 метод assertRaises стал поддерживать использование в качестве контекстного менеджера, что упростило проверку исключений в блоках кода.
В Python 3.4 добавлен метод assertRaisesRegex как замена устаревшему assertRaisesRegexp.
Начиная с Python 3.8, в сообщении об ошибке улучшено отображение информации при использовании контекстного менеджера.
В Python 3.11 были оптимизированы внутренние механизмы unittest, что повысило производительность выполнения тестов с assertRaises.
Расширенные примеры
Проверка нескольких типов исключений с помощью кортежа:
class TestAdvanced(unittest.TestCase):
def test_multiple_exceptions(self):
with self.assertRaises((ValueError, TypeError)):
# Возбуждает ValueError
int(None)
def test_exception_attributes(self):
with self.assertRaises(OSError) as cm:
open('несуществующий_файл.txt')
self.assertEqual(cm.exception.errno, 2)
self.assertEqual(cm.exception.filename, 'несуществующий_файл.txt')Использование с пользовательскими исключениями:
class CustomError(Exception):
pass
def risky_function(x):
if x < 0:
raise CustomError('Отрицательное значение')
return x * 2
class TestAdvanced(unittest.TestCase):
def test_custom_exception(self):
self.assertRaises(CustomError, risky_function, -5)
def test_custom_with_context(self):
with self.assertRaises(CustomError) as context:
risky_function(-10)
self.assertIn('Отрицательное', str(context.exception))Интеграция с mock-объектами:
from unittest.mock import Mock
class TestAdvanced(unittest.TestCase):
def test_with_mock(self):
mock_obj = Mock()
mock_obj.method.side_effect = ValueError('Имитация ошибки')
with self.assertRaises(ValueError):
mock_obj.method()
mock_obj.method.assert_called_once()Проверка исключений в асинхронном коде (с использованием asynctest или unittest.IsolatedAsyncioTestCase):
import asyncio
async def async_risky():
raise RuntimeError('Асинхронная ошибка')
class TestAsync(unittest.IsolatedAsyncioTestCase):
async def test_async_exception(self):
with self.assertRaises(RuntimeError):
await async_risky(). ---------------------------------------------------------------------- Ran 1 test in 0.001s OK
питон unittest.TestCase.assertRaises function comments
- питон unittest.TestCase.assertRaises - аргументы и возвращаемое значение
- Функция python unittest.TestCase.assertRaises - описание
- unittest.TestCase.assertRaises - примеры
- unittest.TestCase.assertRaises - похожие методы на python
- unittest.TestCase.assertRaises на php, c#, sql, java
- unittest.TestCase.assertRaises изменения python
- Примеры unittest.TestCase.assertRaises на питон