Загрузка данных


ПРАКТИЧЕСКАЯ РАБОТА

Тема: Комплексное тестирование и рефакторинг критической бизнес-логики методом «Белого ящика»

ЦЕЛЬ РАБОТЫ
Освоить навыки глубокого анализа исходного кода со сложной бизнес-логикой, выявлением скрытых уязвимостей, состояний гонки (Race Condition), мутаций данных, некомпенсированных транзакций и ошибочной обработки граничных условий. Научиться проводить рефакторинг и составлять исчерпывающее тестовое покрытие.

МЕТОДИКА ВЫПОЛНЕНИЯ
1. Анализ требований и поиск логических уязвимостей

Проанализируйте представленный код функции и сопоставьте его с техническим заданием. Найдите логические изъяны:

●	Побочные эффекты (Side Effects) и непреднамеренные мутации входных объектов;

●	Ошибки в обработке отрицательных значений, нуля, типов null / undefined / NaN;

●	Нарушение атомарности операций и логики ветвления при комбинации флагов;

●	Ошибки в математических округлениях и плавающей точке (Float Precision Issue).

2. Проведение рефакторинга

Перепишите функцию, устранив все выявленные архитектурные и логические дефекты:

●	Обеспечьте чистоту функции (Pure Function) или изолированность изменений;

●	Исправьте порядок проверок (Guard Clauses);

●	Корректно обработайте все edge-cases (граничные сценарии).

3. Разработка полного тестового покрытия

Составьте набор тестов, покрывающий:

●	Положительные сценарии (Happy Path);

●	Граничные условия и экстремальные значения (Boundary Conditions);

●	Негативные сценарии (передача некорректных или поврежденных данных).

СТРУКТУРА ОТЧЕТА ПО ПРАКТИЧЕСКОЙ РАБОТЕ
Отчет оформляется студентом в текстовом редакторе со следующими разделами:

1. Титульный блок

●	Наименование учебного заведения, кафедры и дисциплины

●	Тема практической работы

●	Сведения о студенте (ФИО, группа, номер варианта) и преподавателе

2. Исходные данные

●	Текст задания и исходный код функции с ошибками

3. Аналитическая часть (Аудит кода)

●	Детализированный список всех найденных ошибок и уязвимостей с объяснением, к какому сбою в реальной системе (например, списанию лишних денег или зависанию сессии) приведет каждая из них

4. Рефакторинг (Исправленный код)

●	Итоговый исправленный вариант функции с комментариями к ключевым изменениям

5. Набор тестовых сценариев

●	Список проверочных тестов: идентификатор теста, проверяемая ветка/сценарий, входные аргументы, ожидаемое поведение (возврат значения или проброс ошибки) и фактический результат

6. Вывод по работе

●	Анализ влияния проведенного рефакторинга на надежность, безопасность и поддерживаемость модуля

ВАРИАНТЫ ЗАДАНИЙ ДЛЯ САМОСТОЯТЕЛЬНОЙ РАБОТЫ
Вариант 1. Модуль проведения транзакции и применения промокодов в корзине
Технические требования:

1.	Функция принимает объект cart (корзину) и объект promo.

2.	Если в корзине нет товаров или она не валидна, выбрасывать исключение Error("Empty cart").

3.	Базовая скидка по промокоду не должна быть больше 50% от суммы заказа.

4.	Если пользователь является VIP-клиентом (cart.user.isVip === true), ему начисляется дополнительная скидка 10% на итоговую сумму после применения промокода.

5.	Промокоды одноразовые: если промокод уже использован (promo.isUsed === true), скидка не применяется. После успешного применения статус промокода должен меняться на isUsed = true.

6.	Функция должна возвращать итоговую сумму с точностью до 2 знаков после запятой, не изменяя исходные цены товаров в объекте cart.

Код с ошибками:

JavaScript
function processPayment(cart, promo) {
    let total = 0;

    // 1. Некорректная проверка массива товаров
    for (let i = 0; i <= cart.items.length; i++) { 
        total += cart.items[i].price * cart.items[i].count;
    }

    // 2. Ошибка работы с объектом promo и состояниями
    if (promo && promo.isUsed = false) { 
        if (promo.discountPercent > 50) {
            promo.discountPercent = 50;
        }
        total = total - (total * (promo.discountPercent / 100));
        promo.isUsed = true; // Побочный эффект при незавершенной операции
    }

    // 3. Логическая ошибка в проверке VIP и мутация входных данных
    if (cart.user.isVip = true) {
        total = total * 0.9;
        cart.user.bonusPoints += total * 0.05; // Мутация объекта
    }

    // 4. Проблема плавающей точки и отрицательных сумм
    if (total < 0) return 0;
    
    return total; // Нет округления до 2 знаков
}

Вариант 2. Системный модуль бронирования и распределения слотов ресурсов
Технические требования:

1.	Функция bookSlot принимает массив доступных слотов slots (объекты с id, startTime, endTime, isBooked), желаемый интервал request (startTime, endTime) и userId.

2.	Интервал считается корректным, если startTime < endTime и время начала не находится в прошлом относительно системного времени.

3.	Слоты бронируются, только если желаемый интервал полностью помещается внутри одного свободно находящегося слота (isBooked === false).

4.	При успешном бронировании выбранный слот должен помечаться как isBooked = true, привязываться к userId, а функции должен возвращаться объект ответа { success: true, slotId: ... }.

5.	Если подходящего слота нет или входные данные некорректны, функция должна возвращать { success: false, reason: "..." } без изменения состояния исходных слотов.

Код с ошибками:

JavaScript
function bookSlot(slots, request, userId) {
    // 1. Отсутствие проверки на корректность дат и прошедшее время
    if (request.startTime > request.endTime) {
        return { success: false, reason: "Invalid time" };
    }

    for (let i = 0; i < slots.length; i++) {
        let slot = slots[i];

        // 2. Ошибка в проверке пересечения интервалов и флага
        if (slot.isBooked == false || slot.startTime <= request.startTime) {
            
            // 3. Ранняя мутация до полной проверки интервала окончания
            slot.isBooked = true; 
            slot.userId = userId;

            if (slot.endTime >= request.endTime) {
                return { success: true, slotId: slot.id };
            }
        }
    }

    // 4. Частично мутированные слоты остаются с измененным флагом isBooked!
    return { success: false, reason: "No slot found" };
}

ВОПРОСЫ ДЛЯ САМОПРОВЕРКИ И ЗАЩИТЫ РАБОТЫ
1.	Что такое «чистая функция» (Pure Function) и почему функции с побочными эффектами (Side Effects) сложно тестировать методом «Белого ящика»?

2.	К каким последствиям в многопоточной или асинхронной среде приводит ранняя мутация состояния объекта до завершения всех валидаций?

3.	В чем заключается опасность оператора присваивания (=) внутри условных конструкций if и как ее предотвратить на уровне линтеров и тестов?

4.	Как правильно тестировать код, работающий с финансовыми данными и числами с плавающей точкой (0.1 + 0.2 !== 0.3)?

5.	Что такое паттерн Guard Clauses (защитные условия) и как он упрощает вложенную логику if-else?