Программирование на основе классов и шаблонов

Отладка и тестирование объектно-ориентированных программ

Аладин Дмитрий Владимирович

iu5edu.ru/wiki/cpp2

План

  1. Отладка. Процесс отладки.
  2. Виды ошибок и общие стратегии отладки.
  3. Тестирование ПО. Виды тестирования.
  4. Тестирование и ООП.
  5. Специфика тестирования объектно-ориентированных программ.
  6. Тестирование и паттерны ООП.
  7. Принципы и методики отладки программ с учетом объектов и классов.
  8. Пирамида тестирования ПО.

Следующий материал успешно украден адаптирован с amazon.com, intellect.icu, testengineer.ru, petrsu.ru, practicum.yandex.ru и др.

Другие источники смотрите в "дополнительном материале".

Адаптированный материал публикуется с сохранением условий распространения.

Сегодня нас ждут

  • мемы и точка.

Что такое отладка?

Отладка – это процесс поиска и исправления ошибок или неполадок в исходном коде какого-либо программного обеспечения.

Зарождение "отладки"

Термин берёт своё начало от адмирала Грейс Хоппер, которая работала в Гарвардском университете в 1940-х годах. Когда один из ее коллег обнаружил моль (bug), мешающую работе одного из компьютеров университета, она сказала, что они отлаживают (debugging) систему. Компьютерные программисты впервые стали использовать термины "ошибки" и "отладка" в 1950-х годах, а к началу 1960-х годов термин "отладка" стал общепринятым в сообществе программистов.

Грейс Хоппер

Грейс Хоппер — американский учёный и коммодор (контр-адмирал младшего ранга) флота США, изобретательница первого компилятора. Будучи первооткрывательницей в своей области, она была одной из первых, кто писал программы для гарвардского компьютера Марк I.

Марк I

Марк I (Automatic Sequence Controlled Calculator, сокращённо ASCC — автоматический вычислитель, управляемый последовательностями) — одна из первых в США вычислительных машин с возможностью программирования. Разработан и построен в США в 1944 году.

P.S. сложение: 3 операции в секунду; умножение: 6 секунд; деление — 15,3 сек.

Почему отладка важна?

Как работает процесс отладки?

  • Определение ошибки
  • Анализ ошибки
  • Устранение и проверка
  • Сравнение отладки и тестирования

P.S. Отладка и тестирование – это взаимодополняющие процессы, которые гарантируют, что программы работают должным образом.

Какие ошибки кодирования требуют отладки?

Синтаксические ошибки

– возникает, когда в компьютерной программе неправильно указано значение.

center

Семантические ошибки

Семантические ошибки возникают из-за неправильного использования операторов программирования.

#include <iostream>

int main() {
  std::cout << "Enter an integer: ";
  int x{};
  std::cin >> x;

  if (x >= 5)  // упс, мы использовали operator>= вместо operator>
    std::cout << x << " is greater than 5";

  return 0;
}

Логические ошибки

Логические ошибки возникают, когда программисты искажают поэтапный процесс или алгоритм компьютерной программы.

int average(int a, int b) {
  return a + b / 2; /* правильная запись (a + b) / 2 */
}
как программист кипятит воду в чайнике?
1. Набирает воду в чайник
2. Ставит чайник на огонь
3. Ждет пока тот не вскипит

как программист кипятит воду в чайнике если в нем уже есть вода?
1. Выливает воду из чайника что сводит задачу к уже решенной

Ошибки времени выполнения

Ошибки времени выполнения возникают из-за среды вычисления, в которой выполняется программный код.

Общие стратегии отладки

Пошаговая разработка программы

– это разработка программ в управляемых разделах с целью тестирования небольших частей кода.

Возврат

– разработчики работают в обратном порядке с места, где произошла фатальная ошибка, чтобы определить точную точку ее возникновения в коде.

center

Удаленная отладка

– это отладка приложения, работающего в отличной от вашей локальной машины среде.

center

Ведение журналов

А что если в сборщиках ошибок есть свои ошибки? 😈

Log4Shell (CVE-2021-44228) — это уязвимость нулевого дня в Log4j, популярной среде ведения журналов Java, включающая выполнение произвольного кода. Её существование не было замечено с 2013 года и публично раскрыта 9 декабря 2021 года.

P.S. Ransomware - зловредное программное обеспечение

Отладка в облаке

– это сложная задача, поскольку разработчикам приходится эмулировать облачные архитектуры на локальных компьютерах.

center

Так причем тут ООП?

Что меняется в отладке при использовании ООП?

Чтобы ответить на эти вопросы, нужно вспомнить о том:

  • какие были причины появления ООП;
  • какие возможности появляются при использовании ООП.

Отладка – это "процесс интерактивного запуска программы/метода, причем поток выполнения после каждой инструкции приостанавливается, и отображается результат…". В сущности, это очень дельная техника… для плохого программиста. Или для олдскульного программиста, который все еще пишет процедурный код на C. Специалисты по ООП не отлаживают код — они пишут модульные тесты. Берусь утверждать, что модульное тестирование полностью снимет отладку с повестки дня. Если требуется отладка, значит программа спроектирована плохо.

Мэтт Вайсфельд. Объектно-ориентированное мышление

center

Пришло время разобраться с тем, что такое тестирование и причем там модульность!

Тестирование ПО

Тестирование ПО — процесс исследования ПО с целью получения информации о качестве продукта. ISO 9126 - оценочные характеристики качества.

Цели тестирования:

  • Обнаружение дефектов
  • Повышение уверенности в уровне качества
  • Предоставление информации для принятия решений
  • Предотвращение дефектов

Тестирование ПО (Software Testing) — проверка соответствия между реальным и ожидаемым поведением программы, осуществляемая на конечном наборе тестов, выбранном определенным образом.

IEEE Guide to Software Engineering Body of Knowledge, SWEBOK, 2004

В более широком смысле, тестирование - это одна из техник контроля качества, включающая в себя активности по планированию работ (Test Management), проектированию тестов (Test Design), выполнению тестирования (Test Execution) и анализу полученных результатов (Test Analysis).

Виды тестирования

IEEE 829-2008 - Документация по тестированию программного обеспечения

center

Тестирование и принципы ООП

  • Инкапсуляция создает проблему видимости данных, так как они доступны только через операции. В процессе тестирования это может создать определенные проблемы с выводом значений.
  • Наследование ставит вопросы о повторении тестирования наследуемых операций.
  • Полиморфизм приводит к неоднозначности с вызовом операций, которая может быть разрешена только на этапе выполнения.

Что требуется учитывать при тестировании объектно-ориентированных программ

  • Какая часть унаследованных свойств должна заново тестироваться?
  • Когда и как можно проверять информациию о состоянии класса?
  • Как можно проверить поведение системы, зависящее от состояния, когда отсутствует единый механизм управление состояниями в программе?
  • Как следует тестировать интеграцию классов и какие стратегии тестирования применять?

Выбор базового компонента для тестирования

  • Основной единицей тестирования должен являться класс (объект).
  • Отдельные методы класса бесполезно рассматривать в отрыве от самого класса, а прочие компоненты являются обычно агрегацией классов.
  • Предназначение класса в системе (например, абстрактный класс) определяет особенности его тестирования.

Тестирование экземпляра класса (объекта) может проводится изолированно, однако класс можно считать полностью протестированным, только после того как его экземпляр будет создан и проверен в рамках системы.

Тестирование инкапсуляции

Инкапсуляция, сама по себе, не является источником ошибок, однако представляет препятствие для проведения тестирования, так как при тестировании требуется получение полной информации о состоянии класса, в том числе и всех его атрибутов, многие из которых могут быть объявлены как "невидимые" извне.

Решение этой проблемы может быть найдено в определении специальных отладочных методов, возвращающих информацию о состоянии класса или в использовании низкоуровневых отладчиков программного кода.

center

Тестирование public методов

  • Статические методы
    • Аналогично функциям + специфика ООП
  • Не статические методы
    • Создание экземпляра класса
    • Установка свойств класса
    • Вызов метода у экземпляра
    • Специфика ООП (далее пояснение)

Тестирование protected методов

  • Тестирование через класс-наследник
  • Статические методы
    • Вызов через статический метод класса наследника
  • Нестатические методы
    • Создание экземпляра класса-наследника
      – Установка свойств класса через класс-наследник
      – Вызов метода у экземпляра через класс-наследник
      – Специфика ООП

Тестирование private методов

  • Нет доступа ни напрямую ни через наследники
  • Косвенное тестирование (через public/protected методы)
    • Использование специфики ООП конкретного языка (дружественные классы, рефлексии, ...)

Специфика тестирования объектно-ориентированных программ

  • Тестируемый метод может использовать:
    • Методы и свойства класса
    • Экземпляры классов в качестве параметров
    • Экземпляры классов внутри кода (создание/получение)
    • Внешние сущности: глобальные объекты, статические методы других классов, файлы, потоки данных, …
  • Должна существовать возможность подмены зависимостей (SOLID: L - Принцип подстановки Барбары Лисков). С этим тесно связаны объекты-"заглушки" mock-объекты).

Тестирование и паттерны ООП

  • Подмена зависимостей (в т.ч. для структурных паттернов)
  • Наследование объектов (в т.ч. для порождающих паттернов)
  • Отдельная реализация методов (в т.ч. для паттернов поведения)

Тестирование наследования

Наследуемые методы должны быть протестированы заново при переопределении или дополнении базового метода.

Это связано с тем, что новый контекст атрибутов, новые аспекты поведения могут добавить новые ошибки.

center

Тестирование полиморфизма

Каждый возможный вариант полиморфного вызова метода должен быть протестирован.

Тестирование "белого" и "черного" ящика

center

Тестирование "белого" ящика

— метод тестирования ПО, который предполагает, что внутренняя структура/устройство/реализация системы известны тестировщику.

Согласно ISTQB (International Software Testing Qualifications Board, Совет по сертификации тестирования программного обеспечения), тестирование белого ящика — это:

  • тестирование, основанное на анализе внутренней структуры компонента или системы;
  • тест-дизайн, основанный на технике белого ящика — процедура написания или выбора тест-кейсов на основе анализа внутреннего устройства системы или компонента.
  • Почему "белый ящик"? Тестируемая программа для тестировщика — прозрачный ящик, содержимое которого он прекрасно видит.

Тестирование "чёрного" ящика

— также известное как тестирование, основанное на спецификации или тестирование поведения — техника тестирования, основанная на работе исключительно с внешними интерфейсами тестируемой системы.

Тестирование "серого" ящика

— метод тестирования ПО, который предполагает комбинацию "белого" и "черного" ящика . То есть, внутреннее устройство программы нам известно лишь частично.

P.S. Запомните эти ящики, так как сейчас еще появится пирамида 🤓

Юниты

Любая программа состоит из юнитов, или модулей, — отдельных блоков и функций. Кнопка добавления товара в корзину, формула калькулятора стоимости, скрипт для формирования карточки товара — всё это отдельные модули.

P.S. troops - войска

Модульное тестирование

Модули взаимодействуют и обеспечивают работу программы или приложения. Чтобы проверить, правильно ли написан модуль, проводят юнит-тесты, или модульное тестирование, — проверку не всего приложения, а одного модуля. Пример юнит-теста — проверка функции подсчёта общей стоимости заказа.

Модульное тестирование проводят сразу после написания кода. Проверить работу кнопки в готовом приложении не получится, потому что на неё уже влияют другие модули.

Пирамида тестирования

  • Юнит-тесты — тестирование отдельных модулей.
  • Интеграционные тесты — тестирование взаимодействия нескольких юнитов.
  • Сквозные (end-to-end) тесты — тестирование работы большого количества юнитов вместе.

Особенности юнит-тестировании

  • Юнит, или модульные тесты, проверяют отдельные блоки и функции написанного кода.
  • Юнит-тесты нужны, чтобы быстро протестировать написанный фрагмент кода и сразу понять, где именно кроется ошибка.
  • Юнит-тесты дешевле и быстрее других, их легко автоматизировать.
  • Чтобы юнит-тест получился, тестируемый модуль должен быть изначально изолирован от другого кода (опять SOLID?). Если нужны какие-то зависимости, их имитируют заглушками — моками (ну тут точно SOLID!).

Вопросы?

center

If not, just clap your hands!