Загрузил ovborisov

лабораторная работа N3

НЕГОСУДАРСТВЕННОЕ ОБРАЗОВАТЕЛЬНОЕ ЧАСТНОЕ УЧРЕЖДЕНИЕ
ВЫСШЕГО ОБРАЗОВАНИЯ «МОСКОВСКИЙ ФИНАНСОВОПРОМЫШЛЕННЫЙ УНИВЕРСИТЕТ “СИНЕРГИЯ”
Факультет/Институт
Направление/специальность
подготовки:
Информационные технологии
(наименование факультета/ Института)
09.02.07 Информационные системы и
программирование
(код и наименование направления
/специальности подготовки)
очная
Форма обучения:
(очная, очно-заочная, заочная)
Отчет по лабораторной работе 3
на тему
Лабораторный практикум 3 «Разработка модульных тестов и
достижение 100% покрытия кода»
(наименование темы)
по дисциплине
Проектирование и дизайн информационных систем
(наименование дисциплины)
Обучающийся
Группа
Преподаватель
Бондарь Николай
(ФИО)
ДКИП 312
Скопин Владимир Игоревич
(ФИО)
Москва 2025
(подпись)
(подпись)
Лабораторная работа №3
Тема: «Разработка модульных тестов и достижение 100% покрытия кода»
Цель работы
Освоить принципы модульного тестирования, применение фреймворков тестирования
(например, xUnit, NUnit, MSTest), а также научиться анализировать и повышать покрытие
кода тестами до 100%.
1. Выбор проекта для тестирования:
Для тестирования был выбран проект «Менеджер задач» — работа со списком задач:
(CRUD-операции), фильтрации, поиск, исключения при некорректных данных.
Его консольный вариант, реализованный на языке C# .NET 8 со следующей
структурой:
Рис 1. Структура и классы проекта
Рис 2. Структура и классы проекта Тестирования
В настоящей работе реализована классическая структура — отдельный проект
для приложения и отдельный для тестов.
Методы включают

условия if/else, switch или циклы;

обработку исключений;
2. Модульные тесты:
Для модульного тестирования были разработаны и использовались тесты на основе
xUnit.
Полные тексты Проекта и Проект с тестами прилагаются к отчету
3. Покрытие кода
Для исследования покрытия кода использовался инструмент coverlet и или встроенные
средства IDE.
Скриншоты работы с покрытием кода.
Рис 3. Запуск тестов на покрытие кода.
Рис 4 Результаты проведенного теста на покрытие кода
4. Полный запуск всех тестов
Рис.5 Зпуск тестирования
Рис 6. Результаты тестирования и поиск ошибочного места в программе.
После проведения автоматического тестирования осуществляется экспертный
анализ «плохих» тестов. Общий алгоритм приведен на рисунке 6. Действия 1,2,3 приводят
к проявлению в правой половине окна cтека, вызвавшего ошибку и шаг 4 приводит (при
двойном нажатии к месту в программе, которое ее вызвало (шаг 5 ). Здесь необходимо
принять решение, что делать с кодом.
Рис 7. Результаты тестирования после исправления ошибочного кода
Вопросы
1. Чем отличаются модульные, интеграционные и системные тесты?
Модульные тесты (Unit Tests)

Что тестируют:
Отдельные "единицы" - классы, методы

Изоляция:
Полная. Все зависимости заменяются "муляжами"

Скорость:
Очень быстрые (миллисекунды)

Пример:
Проверка, что метод AddTask() правильно создает задачу
Интеграционные тесты (Integration Tests)

Что тестируют: Взаимодействие нескольких компонентов

Изоляция: Частичная. Используются реальные БД, файлы, API

Скорость: Средние (секунды)

Пример: Проверка, что TaskManager корректно сохраняет задачи в базу данных
Системные тесты (System Tests / E2E)

Что тестируют: Всю систему целиком

Изоляция: Минимальная. Все реальные компоненты

Скорость: Медленные (минуты/часы)

Пример: Полный сценарий: пользователь открывает приложение → создает задачу
→ отмечает выполненной → удаляет
Ключевые отличия:
Масштаб: Метод → Компоненты → Вся система
Изоляция: Полная → Частичная → Практически нет
Скорость: Быстро → Средне → Медленно
Цель: Корректность логики → Корректность взаимодействия → Работоспособность
системы
Пирамида тестирования (идеальное соотношение):

70% - Модульные (быстрые, надежные)

20% - Интеграционные (проверяют интеграции)

10% - Системные (проверяют полные сценарии)
Простая аналогия:

Модульные = Проверка двигателя отдельно от машины

Интеграционные = Проверка как двигатель работает с коробкой передач

Системные = Тест-драйв всей готовой машины
2.
Почему невозможно гарантировать качество только на основе 100%
покрытия?
100% покрытие говорит: "Мы вызвали каждую строку кода".
Но не говорит: "Мы проверили все возможные сценарии работы".
Например:
Тест вызывает метод Calculate(2, 2) → покрытие 100%
Но не тестирует Calculate(0, 0), Calculate(-1, 1000), Calculate(null, null)
3.
Какие типы покрытия существуют (по строкам, по ветвям, по условиям)
Выделяют следующие типы покрытия кода
1. Покрытие по строкам (Line Coverage)
Что: Сколько строк кода было выполнено
Простота: Легко достичь, но недостаточно
2. Покрытие по ветвям (Branch Coverage)
Что: Все ветви if/else, switch протестированы
Строже: Требует тестировать ВСЕ варианты выполнения
Пример: if-else → нужно протестировать обе ветки
3. Покрытие по условиям (Condition Coverage)
Что: Все комбинации логических условий проверены
Самый строгий: if (A && B) → нужно 4 теста для всех комбинаций A и B
Практически: Часто недостижимо для сложных условий
4. Покрытие по путям (Path Coverage)
Что: Все возможные пути выполнения программы
Теоретически идеально, но экспоненциально сложно
Редко используется на практике из-за сложности
Иерархия от слабого к строгому:
Строки → Ветви → Условия → Пути
Чем правее, тем: надежнее качество тестов, НО сложнее достичь и дороже в
поддержке
4.
Какую роль играют mock-объекты?
Mock-объекты это: искусственные объекты, которые имитируют поведение
реальных зависимостей в тестах.
Основные роли:
1.Изоляция тестов
-
Тестируем ОДИН компонент, не зависимо от других,
Проблемы
-
в базе данных/API не ломают unit-тесты
2.Контроль зависимостей -
Задаём точное поведение: "верни эти данные",
"вызовись 3 раза"
Создаём нужные сценарии -
: успех, ошибка, исключение
3. Ускорение тестов
Не ходим в реальную БД (медленно).Не зависим от
-
сети/внешних сервисов
4. Тестирование труднодоступных сценариев - "А что если сервер упадет?",
"А если БД вернёт 10 миллионов записей?","А если файловая система переполнена?"
5. Проверка взаимодействия
-
"Метод А вызвал метод Б с правильными
параметрами?","Сколько раз вызвался внешний сервис?"
4.
Что делать, если добиться 100% покрытия невозможно?
Сфокусироваться на важном : бизнес-логика должна обладать максимальным
покрытием.
Можно писать вспомогательный код.
Установить реалистичные цели:
80-90% по строкам - хороший уровень
70-80% по ветвям - достаточная надежность
Использовать исключения