Уровень 1. Базовые Unit-тесты
На этом уровне необходимо научиться:
- создавать класс с тестами;
- использовать unittest.TestCase;
- применять методы assertEqual, assertTrue, assertFalse, assertIsNone, assertRaises;
- проверять корректные и граничные значения.
⸻
Задача 1. Проверка возраста клиента
Тикет
Проект: Интернет-магазин электроники
Отдел: Юридический
После обновления законодательства компания обязана проверять возраст покупателей при оформлении товаров категории 18+.
Разработчик реализовал функцию проверки возраста. Юридический отдел просит убедиться, что она работает корректно во всех типовых сценариях.
⸻
Реализованная функция
def is_adult(age: int) -> bool:
...
⸻
Описание
Функция принимает возраст пользователя.
Возвращает:
- True, если возраст 18 лет или больше
- False, если меньше 18.
⸻
Необходимо протестировать
Подумайте, какие проверки должны существовать.
Например:
- минимальный допустимый возраст;
- возраст меньше минимального;
- ноль;
- отрицательное число;
- большое значение.
⸻
⸻
Задача 2. Проверка скидочного купона
Тикет
Проект: Интернет-магазин одежды
Отдел: Маркетинг
Во время акции используется функция проверки промокодов.
Маркетинг сообщил, что несколько клиентов получили скидку по невалидным кодам.
Необходимо написать набор unit-тестов.
⸻
Реализованная функция
def is_valid_coupon(code: str) -> bool:
...
⸻
Правила
Купон считается корректным, если:
- начинается с SALE-
- после дефиса ровно четыре цифры
Корректные примеры:
SALE-1234
SALE-0001
SALE-9999
Некорректные:
sale-1234
SALE1234
SALE-12
SALE-12345
DISCOUNT-1234
⸻
Необходимо протестировать
Определите полный набор тестов самостоятельно.
⸻
⸻
Задача 3. Проверка деления
Тикет
Проект: Финансовый калькулятор
Отдел: Аналитика
Функция используется в расчётах отчётов.
После нескольких аварийных завершений программы необходимо проверить её работу.
⸻
Реализованная функция
def divide(a: float, b: float) -> float:
...
⸻
Требования
Функция должна:
- возвращать результат деления;
- при делении на ноль возбуждать исключение ZeroDivisionError.
⸻
Необходимо протестировать
Продумайте проверки:
- обычное деление;
- отрицательные числа;
- деление на единицу;
- деление на ноль;
- дробные значения.
⸻
Уровень 2. Работа со строками, коллекциями и исключениями
На этом уровне потребуется:
- использовать разные виды assert;
- проверять содержимое списков;
- тестировать исключения;
- проверять несколько сценариев работы функции.
⸻
Задача 4. Фильтрация активных пользователей
Тикет
Проект: CRM-система
Отдел: Продажи
Менеджеры жалуются, что в ежедневный отчёт иногда попадают заблокированные пользователи.
Разработчик утверждает, что ошибка отсутствует.
Необходимо подготовить unit-тесты.
⸻
Реализованная функция
def get_active_users(users: list[dict]) -> list[dict]:
...
⸻
Каждый пользователь имеет вид
{
"name": "...",
"active": True
}
Функция должна вернуть только активных пользователей.
⸻
Необходимо протестировать
Рассмотрите различные случаи:
- пустой список;
- все пользователи активны;
- все заблокированы;
- смешанный список;
- один пользователь.
⸻
⸻
Задача 5. Поиск товара
Тикет
Проект: Складская система
Отдел: Логистика
Во время инвентаризации сотрудники заметили, что некоторые товары не находятся поиском.
Необходимо убедиться в корректности функции.
⸻
Реализованная функция
def find_product(products: list[str], name: str) -> int:
...
⸻
Функция должна вернуть индекс товара.
Если товар отсутствует —
должна возбуждаться ошибка
ValueError
⸻
Необходимо протестировать
Подберите проверки самостоятельно.
Особое внимание уделите:
- первому элементу;
- последнему элементу;
- отсутствующему товару;
- пустому списку.
⸻
⸻
Задача 6. Расчёт среднего балла
Тикет
Проект: Электронный дневник
Отдел: Образование
После внедрения новой версии появились жалобы на некорректный расчёт среднего балла.
⸻
Реализованная функция
def average(scores: list[int]) -> float:
...
⸻
Если список пустой —
должно возбуждаться
ValueError
⸻
Необходимо протестировать
Продумайте проверки для:
- одного значения;
- нескольких значений;
- дробного результата;
- пустого списка;
- отрицательных чисел (если функция их допускает).
⸻
Уровень 3. Реальные бизнес-сценарии
На этом уровне функции содержат больше бизнес-логики.
Задача — определить полный набор тест-кейсов самостоятельно.
⸻
Задача 7. Проверка банковского перевода
Тикет
Проект: Интернет-банк
Приоритет: High
После релиза обнаружены случаи проведения некорректных переводов.
Необходимо проверить функцию в максимальном количестве сценариев.
⸻
Реализованная функция
def can_transfer(balance: float, amount: float) -> bool:
...
⸻
Перевод разрешён, если:
- сумма больше нуля;
- баланс достаточен;
- сумма не превышает 100000.
Во всех остальных случаях возвращается False.
⸻
Необходимо протестировать
Подготовьте полный набор unit-тестов.
⸻
⸻
Задача 8. Авторизация пользователя
Тикет
Проект: Корпоративный портал
Отдел: Информационная безопасность
После обновления системы появились обращения пользователей, которые не могут войти в систему.
Требуется проверить функцию авторизации.
⸻
Реализованная функция
def login(username: str, password: str) -> bool:
...
⸻
Функция должна вернуть:
- True, если логин и пароль корректны;
- False — иначе.
⸻
Известные учётные данные:
admin
Qwerty123
⸻
Необходимо протестировать
Определите необходимые проверки самостоятельно.
Рекомендуется обратить внимание на:
- регистр символов;
- пустые строки;
- неверный логин;
- неверный пароль;
- полностью корректные данные.
⸻
⸻
Задача 9. Расчёт стоимости доставки
Тикет
Проект: Сервис доставки
Заказчик: Отдел логистики
После изменения тарифов необходимо убедиться, что расчёт стоимости выполняется корректно.
⸻
Реализованная функция
def delivery_price(weight: float) -> int:
...
⸻
Правила:
до 1 кг → 300
1–5 кг → 500
5–20 кг → 800
более 20 кг → 1500
При отрицательном весе должно возбуждаться
ValueError
⸻
Необходимо протестировать
Определите полный набор тестов.
Особое внимание уделите:
- всем границам диапазонов;
- значениям непосредственно до и после границ;
- отрицательным значениям;
- нулевому весу;
- очень большому весу.
⸻
Дополнительное задание
После выполнения всех 9 задач проведите ревью своих тестов и ответьте на вопросы:
- Есть ли в тестах дублирование кода?
- Можно ли вынести подготовку данных в метод setUp()?
- Проверяет ли каждый тест только один сценарий?
- Достаточно ли покрыты граничные значения?
- Проверяются ли не только успешные, но и ошибочные сценарии?
- Можно ли понять причину падения теста по его названию?
- Используются ли наиболее подходящие методы assert* вместо универсального assertTrue?