Ответ
Процесс написания тестов для функции строится вокруг стандартного паттерна Arrange-Act-Assert (AAA) или Given-When-Then.
Общий алгоритм:
-
Определение сценариев: Проанализировать функцию и определить, что нужно протестировать.
- Позитивные сценарии: Работа с корректными, ожидаемыми данными.
- Негативные сценарии: Реакция на некорректные данные (неверный тип, формат).
- Граничные случаи: Проверка на крайних значениях (пустые строки,
0,None, максимальные значения).
-
Написание теста для каждого сценария по структуре AAA:
- Arrange (Подготовка): Создать все необходимые условия и входные данные для теста. Инициализировать объекты, подготовить моки (mocks).
- Act (Действие): Вызвать тестируемую функцию с подготовленными данными.
- Assert (Проверка): Сравнить полученный результат с ожидаемым. Убедиться, что состояние системы изменилось так, как предполагалось, или что было вызвано нужное исключение.
Пример с pytest для функции add:
# Функция, которую мы тестируем
def add(a, b):
if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):
raise TypeError("Оба аргумента должны быть числами")
return a + b
# --- Тесты ---
import pytest
def test_add_positive_numbers():
# Arrange (Подготовка)
num1 = 5
num2 = 10
expected_result = 15
# Act (Действие)
actual_result = add(num1, num2)
# Assert (Проверка)
assert actual_result == expected_result
def test_add_negative_numbers():
# AAA в одну строку для простых случаев
assert add(-2, -3) == -5
def test_add_with_zero():
assert add(10, 0) == 10
def test_add_raises_type_error_for_string():
# Для проверки исключений используется контекстный менеджер
with pytest.raises(TypeError):
# Act & Assert происходят здесь
add("2", 3) Ответ 18+ 🔞
Давай разберём эту тему, но без занудства, а как есть. Смотри, есть у тебя функция, и ты хочешь убедиться, что она не накосячит в продакшене. Как к этому подступиться? А подступаться надо с умом, по чёткому плану, а не как мартышлюшка с гранатой.
Вот смотри, алгоритм такой, что хоть на стенке пиши:
1. Прикинь, где она может наебнуться. Это самый важный этап, ёпта. Не надо сразу писать код. Сядь, посмотри на функцию и подумай: "А что, если ей передать не число, а строку? А что, если пустой список? А если передать None?" Вот эти сценарии и надо выписывать. Позитивные (когда всё ок), негативные (когда всё хуёво) и граничные (когда на самом краю, типа пустая строка или ноль).
2. Для каждого такого сценария пишешь отдельный тест по шаблону "Подготовил-Сделал-Проверил". Это и есть тот самый Arrange-Act-Assert (AAA).
- Arrange (Подготовка): Ты тут как режиссёр перед съёмкой. Расставляешь декорации — создаёшь нужные переменные, подсовываешь моки (это такие заглушки, которые притворяются другими частями системы, чтобы не дергать базу данных или API просто так).
- Act (Действие): Кричишь "Мотор!" и запускаешь свою функцию с этими подготовленными данными.
- Assert (Проверка): Смотришь, что получилось в кадре, и сравниваешь с тем, что должно было быть. Совпало? Отлично. Нет? Пиздец, надо переснимать (то есть чинить код).
Вот смотри на живом примере. Есть у нас функция add, которая складывает два числа. Проще некуда, но и тут можно накосячить.
# Функция, которую мы тестируем
def add(a, b):
if not isinstance(a, (int, float)) or not isinstance(b, (int, float)):
raise TypeError("Оба аргумента должны быть числами")
return a + b
А теперь пишем на неё тесты. Смотри, как это выглядит в pytest:
import pytest
# Тест 1: Проверяем, что с нормальными числами всё ок
def test_add_positive_numbers():
# Arrange (Подготовка)
num1 = 5
num2 = 10
expected_result = 15
# Act (Действие)
actual_result = add(num1, num2)
# Assert (Проверка)
assert actual_result == expected_result # Если тут не 15, тест упадёт с криком
# Тест 2: Можно и покороче, если сценарий простой
def test_add_negative_numbers():
# AAA в одну строку для простых случаев
assert add(-2, -3) == -5
# Тест 3: Граничный случай — ноль
def test_add_with_zero():
assert add(10, 0) == 10
# Тест 4: А вот это важно! Проверяем, что на хуйню функция реагирует правильно
def test_add_raises_type_error_for_string():
# Для проверки исключений используется контекстный менеджер
with pytest.raises(TypeError):
# Act & Assert происходят здесь: если исключение НЕ вылетело — тест провален
add("2", 3) # Пытаемся сложить строку и число
Вот и весь сказ, Колян. Главное — не лениться покрывать эти самые сценарии. Потому что если ты этого не сделаешь, это сделает пользователь, и потом тебе придётся объяснять, почему всё накрылось медным тазом. А доверия к тебе после такого будет, блядь, ноль.