Верификация и проверка правильности

Отладчики типично поддерживают проверку программы, выполняемую самими разработчиками. Перед тем, как работа над программой будет считаться законченной и она может быть передана пользователям, программа обычно подвергается систематическому процессу верификации и проверки правильности (verification and validation – V & V), который выполняется специальными людьми – тестировщиками.

Под верификацией понимают проверку внутренней согласованности, под проверкой правильности – проверку на соответствие внешним спецификациям. В лекции, посвященной инженерии программ, процессу V & V будет уделено больше внимания. На данный момент просто стоит понимать, что соответствующие средства относятся к двум разным категориям.

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

· Динамические методы должны выполнять программу, тестируя ее на соответствие ожидаемым результатам.

Тема 15. Тестирование программного обеспечения

Основные определения. План тестирования. Принципы и методы тестирования ПО. Автономная и комплексная отладка ПО.

В терминологии профессионалов тестирования (программного и некоторого аппаратного обеспечения), фразы «тестирование белого ящика» и «тестирование чёрного ящика» относятся к тому, имеет ли разработчик тестов доступ к исходному коду тестируемого программного обеспечения, или же тестирование выполняется через пользовательский интерфейс либо прикладной программный интерфейс, предоставленный тестируемым модулем. При тестировании методом белого ящика (white-box testing, также говорят — прозрачного ящика, оно же структурное тестирование), разработчик теста имеет доступ к исходному коду программ и может писать код, который связан с библиотеками тестируемого программного обеспечения. На рисунке 4.1 можно увидеть схематическое изображение данного метода. Рисунок 4.1 - Метод белого ящика Тесты создаются на основе знаний о структуре самой системы и о том, как она работает. Критерии полноты основаны на проценте элементов кода, которые отработали в ходе выполнения тестов. Для оценки степени соответствия требованиям могут привлекаться дополнительные знания о связи требований с определенными ограничениями на значения внутренних данных системы (например, на значения параметров вызовов, результатов и локальных переменных).

Тестирование черного ящика, нацеленное на проверку требований. Тесты для него и критерий полноты тестирования строятся на основе требований и ограничений, четко зафиксированных в спецификациях, стандартах, внутренних нормативных документах. Часто такое тестирование называется тестированием на соответствие (conformance testing). Частным случаем его является функциональное тестирование — тесты для него, а также используемые критерии полноты проведенного тестирования определяют на основе требований к функциональности.

Существует классификация видов тестирования, которая основана на том уровне детализации работ проекта, на который оно нацелено. На рисунке 5.1 изображены уровни тестирования. Эти же разновидности тестирования можно связать с фазой жизненного цикла, на которой они выполняются. Модульное тестирование (Unit-testing) — уровень тестирования, на котором тестируется минимально возможный для тестирования компонент, например, отдельный класс или функция. На этом уровне применяются методы «белого ящика». В современных проектах модульное тестирование («юнит-тестинг») осуществляется разработчиками [9]. Модульное тестирование предназначено для проверки правильности отдельных модулей, вне зависимости от их окружения. При этом проверяется, что если модуль получает на вход данные, удовлетворяющие определенным критериям корректности, то и результаты его корректны. Для описания критериев корректности входных и выходных данных часто используют программные контракты — предусловия, описывающие для каждой операции, на каких входных данных она предназначена работать, постусловия, описывающие для каждой операции, как должны соотноситься входные данные с возвращаемыми ею результатами, и инварианты, определяющие критерии целостности внутренних данных модуля. Основной недостаток модульного тестирования состоит в том, что проводить его можно, только когда проверяемый элемент программы уже разработан. Снизить влияние этого ограничения можно, подготавливая тесты (а это — наиболее трудоемкая часть тестирования) на основе требований заранее, когда исходного кода еще нет. Модульное тестирование является важной составной частью отладочного тестирования, выполняемого разработчиками для отладки написанного ими кода.

Интеграционное тестирование (Integration testing) – уровень тестирования, на котором отдельные программные модули объединяются и тестируются в группе. Обычно интеграционное тестирование проводится после модульного тестирования (юнит-тесты для модулей должны быть выполнены и найденные ошибки исправлены) [9]. Интеграционное тестирование в качестве входных данных использует модули, над которыми было проведено модульное тестирование, группирует их в более крупные множества, выполняет тесты, определённые в плане тестирования для этих множеств, и представляет их в качестве выходных данных и входных для последующего системного тестирования. При этом проверяется, что в ходе совместной работы модули обмениваются данными и вызовами операций, не нарушая взаимных ограничений на такое взаимодействие, например, предусловий вызываемых операций.

Интеграционное тестирование выполняется разработчиками используется при отладке, но на более позднем этапе разработки. Системное тестирование (System testing) - это тестирование программного обеспечения, выполняемое на полной, интегрированной системе, с целью проверки соответствия системы исходным требованиям. Системное тестирование относится к методам тестирования «чёрного ящика», и, тем самым, не требует знаний о внутреннем устройстве системы. Системное тестирование выполняется через внешние интерфейсы программного обеспечения и тесно связано с тестированием пользовательского интерфейса (или через пользовательский интерфейс), проводимым при помощи имитации действий пользователей над элементами этого интерфейса. Частными случаями этого вида тестирования являются тестирование графического пользовательского интерфейса (Graphical User Interface, GUI) и пользовательского интерфейса Web-приложений (WebUI). Системное тестирование выполняется инженерами по тестированию. Приемочное тестирование (Acceptance testing) - это тестирование готового продукта конечными пользователями на реальном окружении, в котором будет функционировать тестируемое приложение. Приемочные тесты разрабатываются пользователями, обычно, в виде сценариев. Для того, чтобы найти больше ошибок рекомендуется планировать не только системное тестирование и приемочное, но и модульное и интеграционное.

татическое тестирование (Static testing) – тестирование, в ходе которого тестируемая программа (код) не выполняется (запускается). Анализ программы происходит на основе исходного кода, который вычитывается вручную, либо анализируется специальными инструментами. Unit Testing Integration Testing System Testing Acceptance Testing21 Примеры статического тестирования: обзоры (Reviews);- инспекции (Inspections);- сквозные просмотры (Walkthroughs);- аудиты (Audits).- Динамическое тестирование (Dynamic testing) – тестирование, в ходе которого тестируемая программа (код) выполняется (запускается). Альфа-тестирование — тестирование в процессе разработки. Бета-тестирование — тестирование выполняется пользователями (end-users).

Перед тем, как выпускается программное обеспечение, как минимум, оно должно проходить стадии альфа (внутреннее пробное использование) и бета (пробное использование с привлечением отобранных внешних пользователей) версий. Отчеты об ошибках, поступающие от пользователей этих версий продукта, обрабатываются в соответствии с определенными процедурами, включающими подтверждающие тесты (любого уровня), проводимые специалистами группы разработки. Данный вид тестирования не может быть заранее спланирован. Регрессионное тестирование (Regression testing) – тестирование функциональности, которая была уже протестирована до внесения какого-либо изменения. После внесения изменений в очередную версию программы, регрессионные тесты подтверждают, что сделанные изменения не повлияли на работоспособность остальной функциональности приложения. Регрессионное тестирование может выполняться как вручную, так и средствами автоматизации тестирования. Определение успешности регрессионных тестов (IEEE 610-90 “Standard Glossary of Software Engineering Terminology”) гласит: “повторное выборочное тестирование системы или компонент для проверки сделанных модификаций не должно приводить к непредусмотренным эффектам”. На практике это означает, что если система успешно проходила тесты до внесения модификаций, она должна их проходить и после внесения таковых. Основная проблема регрессионного тестирования заключается в поиске компромисса между имеющимися ресурсами и необходимостью проведения таких тестов по мере внесения каждого изменения. В определенной степени, задача состоит в том, чтобы определить критерии “масштабов” изменений, с достижением которых необходимо проводить регрессионные тесты.

Наши рекомендации