
- •1. Понятие класса. Методы класса. Управление доступом к компонентам.
- •2. Объявление и определение класса. Внешнее определение функций.
- •3. Создание, копирование и удаление объекта.
- •4. Статические компоненты класса. Инициализация статических компонентов класса.
- •5. Наследование. Типы наследования. Виртуальное наследование.
- •6. Виртуальные функции
- •7. Абстрактные классы и чистые виртуальные функции. Интерфейс
- •8. Дружественность. Дружественные классы и функции.
- •9. Вложенные классы. Внутреннее и внешнее определение.
- •10. Шаблоны классов
- •11.Создание экземпляров шаблона. Инстанцирование.
- •12.Шаблоны и наследование.
- •13.Терминология шаблонов.
- •14. Параметры и аргументы шаблона.
- •15. Шаблоны компонентных функций
- •16. Полная специализация шаблонов.
- •17. Частичная специализация шаблонов.
- •18. Перегрузка операций. Основные понятия.
- •19. Перегрузка унарных операций.
- •20. Перегрузка бинарных операций.
- •Int test() {
- •Int test() {
- •Int test() {
- •// Делаем что-то
- •Вопрос 23
- •24. Группировка и композиция исключений. Повторная генерация. Перехват всех исключений.
- •25. Автоматическое управление ресурсами. Методика raii.
- •Void f() { FileOpen("myfile.Txt", "rt"); //здесь выполняем нужную работу с файлом //... }
- •Void f (int a) throw (x2, x3)
- •27. Стандартная библиотека. Организация стандартной библиотеки
- •28. Тип вектора. Вложенные типы. Итераторы. Доступ к элементам
- •29.Тип Вектора. Конструкторы. Операции со стеком. Списочные операции. Размеры и емкость.
- •30. Стандартные контейнеры. Вопросы производительности операций.
- •31. Процесс разработки по. Цели и этапы проектирования.
- •32. Процесс разработки по. Выявление классов. Определение операций.
- •33. Процесс разработки по. Определение взаимосвязей. Определение интерфейсов.
- •Этап 3: выявление зависимостей
- •Этап 4: определение интерфейсов
- •34. Паттерны проектирования. Основные паттерны.
- •35. Тестирование по. Методы тестирования.
35. Тестирование по. Методы тестирования.
Можно считать, что если программа не тестировалась, то она не работает. Идеальное проектирование и такого же качества реализация системы, в результате которых программа абсолютно корректно работает с самого первого запуска, достижимы разве что в самых тривиальных случаях. Стремиться к идеалу надо, но нужно не забывать о необходимости тестирования.
«Как тестировать?» — на этот вопрос нет общего ответа. А вот на вопрос «Когда тестировать?» общий ответ существует: как можно раньше (и как можно чаще). Стратегия тестирования должна быть частью общего проекта или хотя бы разрабатываться параллельно с ним. Как только система может быть запущена, следует начинать ее тестирование. Откладывать серьезное тестирование до момента, когда будет получена почти окончательная реализация — значит обрекать систему на серьезные изъяны, а сроки разработки проекта на срыв.
Если только это вообще возможно, систему нужно проектировать с прицелом на удобство тестирования. В частности, механизмы, облегчающие тестирование, могут встраиваться в саму систему. Часто этого не делают из опасений перегрузить систему и что средства, необходимые для тестирования, чрезмерно расширят структуры данных. Такие опасения совершенно необоснованны, ибо дополнительный тестировочный код и расширения структур данных могут быть удалены перед выпуском окончательной версии. Здесь особо удобен механизм проверочных утверждений (assertions) (§24.3.7.2).
Но еще более важным, чем конкретные тесты, является разработка такой структуры системы, в рамках которой можно быть уверенным в том, что ошибки будут устранены путем комбинации статических проверок, статического анализа и тестирования. Когда разрабатывается общая стратегия устойчивости к ошибкам (§14.9), стратегия тестирования может разрабатываться как дополнительный и тесно связанный с ней аспект общего проектирования.
Если на стадии проектирования вопросы тестирования были забыты, то готовьтесь к тому, что процесс тестирования затянется, сроки сдачи продукта сорвутся, а поддержка продукта усложнится. Обычно хорошим местом для начала работы над стратегией тестирования является этап проектирования, связанный с определением интерфейсов классов и их зависимостями (§24.3, §24.4.2).
Обычно трудно сказать, каков достаточный объем тестирования. На практике недостаточное тестирование встречается гораздо чаще избыточного. Точное количество ресурсов (в том числе человеческих), которые должны быть выделены под тестирование по сравнению с проектированием и реализацией, зависят от природы задачи и от методов, которыми ее решают. Однако в качестве эмпирического правила я могу предположить, что на тестирование нужно выделить больше ресурсов (времени, талантов и т.д.), чем на ее первоначальную реализацию. Тестирование должно сосредотачиваться на ошибках, влекущих за собой катастрофические последствия, а также на менее серьезных проблемах, но которые встречаются чаще других.
Методы тестирования
В терминологии профессионалов тестирования, фразы «тестирование белого ящика» и «тестирование чёрного ящика» относятся к тому, имеет ли разработчик тестов доступ к исходному коду тестируемого ПО, или же тестирование выполняется через пользовательский интерфейс либо прикладной программный интерфейс, предоставленный тестируемым модулем.
При тестировании белого ящика (англ. white-box testing, также говорят — прозрачного ящика), разработчик теста имеет доступ к исходному коду программ и может писать код, который связан с библиотеками тестируемого ПО. Это типично для юнит-тестирования (англ. unit testing), при котором тестируются только отдельные части системы. Оно обеспечивает то, что компоненты конструкции — работоспособны и устойчивы, до определённой степени. При тестировании белого ящика используются метрики покрытия кода или мутационное тестирование.
При тестировании чёрного ящика, тестировщик имеет доступ к ПО только через те же интерфейсы, что и заказчик или пользователь, либо через внешние интерфейсы, позволяющие другому компьютеру либо другому процессу подключиться к системе для тестирования. Например, тестирующий модуль может виртуально нажимать клавиши или кнопки мыши в тестируемой программе с помощью механизма взаимодействия процессов, с уверенностью в том, все ли идёт правильно, что эти события вызывают тот же отклик, что и реальные нажатия клавиш и кнопок мыши. Как правило, тестирование чёрного ящика ведётся с использованием спецификаций или иных документов, описывающих требования к системе. Как правило, в данном виде тестирования критерий покрытия складывается из покрытия структуры входных данных, покрытия требований и покрытия модели (в тестировании на основе моделей).
При тестировании серого ящика разработчик теста имеет доступ к исходному коду, но при непосредственном выполнении тестов доступ к коду, как правило, не требуется.
Если «альфа-» и «бета-тестирование» относятся к стадиям до выпуска продукта (а также, неявно, к объёму тестирующего сообщества и ограничениям на методы тестирования), тестирование «белого ящика» и «чёрного ящика» имеет отношение к способам, которыми тестировщик достигает цели.
Бета-тестирование в целом ограничено техникой чёрного ящика (хотя постоянная часть тестировщиков обычно продолжает тестирование белого ящика параллельно бета-тестированию). Таким образом, термин «бета-тестирование» может указывать на состояние программы (ближе к выпуску чем «альфа»), или может указывать на некоторую группу тестировщиков и процесс, выполняемый этой группой. Итак, тестировщик может продолжать работу по тестированию белого ящика, хотя ПО уже «в бете» (стадия), но в этом случае он не является частью «бета-тестирования» (группы/процесса).
Покрытие кода
Покрытие кода, по своей сути, является тестированием методом белого ящика. Тестируемое ПО собирается со специальными настройками или библиотеками и/или запускается в особом окружении, в результате чего для каждой используемой (выполняемой) функции программы определяется местонахождение этой функции в исходном коде. Этот процесс позволяет разработчикам и специалистам по обеспечению качества определить части системы, которые, при нормальной работе, используются очень редко или никогда не используются (такие как код обработки ошибок и т.п.). Это позволяет сориентировать тестировщиков на тестирование наиболее важных режимов.
Тестировщики могут использовать результаты теста покрытия кода для разработки тестов или тестовых данных, которые расширят покрытие кода на важные функции.
Как правило, инструменты и библиотеки, используемые для получения покрытия кода, требуют значительных затрат производительности и/или памяти, недопустимых при нормальном функционировании ПО. Поэтому они могут использоваться только в лабораторных условиях.