В настоящее время в области информационных технологий и построения программ все большее место занимает построение крупномасштабных программных средств, обладающих мощными интеллектуальными возможностями. Соответственно росту сложности программ возрастает количество выявляемых и остающихся в них дефектов и ошибок.
С технической точки зрения тестирование заключается в выполнении приложения на некотором множестве исходных данных к установить соответствие различных свойств и характеристик приложения заказанным свойствам. Как одна из основных фаз процесса разработки программного продукта (Дизайн приложения – Разработка кода – Тестирование), тестирование характеризуется достаточно большим вкладом в суммарную трудоемкость разработки продукта. Широко известна оценка распределения трудоемкости между фазами создания программного продукта: 40–20–40 %, из чего следует, что наибольший эффект в снижении трудоемкости может быть получен прежде всего на фазах Design и Testing. Задачей ближайшего будущего является движение в сторону такого распределения трудоемкости (60–20–20 %), чтобы суммарная цена обнаружения большинства дефектов стремилась к минимуму за счет обнаружения преимущественного числа ошибок программы на наиболее ранних фазах разработки программного продукта.
Тестирование осуществляется на заданном заранее множестве входных данных X и множестве предполагаемых результатов Yэт – (X, Yэт), которые задают график желаемой функции. Определяется соответствуют ли выходные данные – Yвых (вычисленные по входным данным – X) желаемым результатам – Yэт, т.е. принадлежит ли каждая вычисленная точка (x,yвых) графику желаемой функции (X, Yэт). При выявлении (x,yвых) не принадлежащей (X, Yэт) запускается процедура исправления ошибки, которая заключается во внимательном анализе (просмотре) протокола промежуточных вычислений, приведших к (x, yвых).
Тестирование программного обеспечения представляет собой процесс или последовательность процессов, целью которых является нахождение ошибок в программе. Программа должна вести себя предсказуемо. Не следует, однако, думать, что целью тестирования является демонстрация того, что программа не содержит ошибок. Практически любая программа (кроме самых простых) содержит ошибки, и если тест их не выявил, то такой тест можно считать неудачным. Наоборот, целью тестирования является выявление ошибок в предположении, что они в программе есть. Однако, выявить с помощью тестирования все ошибки, особенно в сложной системе, практически нереально.
Тестирование в случае программ предполагает, что программа выполняется для некоторых исходных данных (тестового набора), и выходные данные сравниваются с эталонными. Если они не совпадают, в программе присутствует ошибка, и ее уже можно найти, так как мы знаем набор исходных данных, который ее провоцирует. На первый взгляд все кажется простым, однако вскоре возникает вопрос о том, как же выбирать тестовые наборы. Решение этой проблемы сильно зависит от тестируемой программы и от целей ее разработки. Желательно, чтобы выбираемые тестовые наборы давали наибольшую вероятность обнаружения ошибки.
Основная проблема тестирования – определение достаточности множества тестов для истинности вывода о правильности реализации программы, а также нахождения множества тестов, обладающего этим свойством. Задача о выборе конечного набора тестов (X, Yэт) для проверки программы в общем случае неразрешима. Поэтому для решения практических задач остается искать частные случаи решения этой задачи.
В настоящей работе рассмотрены подходы к автоматизации решения различных задач тестирования программных систем, причем основное внимание уделено структурному тестированию на граф-моделях программ, выполняемому на ранних стадиях жизненного цикла (модульному тестированию и интеграционному дизайн-тестированию).
Рассмотрены следующие проблемы:
- Выбор множества тестовых путей, обеспечивающего заданное тестовое покрытие.
- Автоматическая оценка полноты тестирования.
- Инструментирование и динамический анализ программ.
- Генерация тестовых воздействий на основе алгебраических моделей программ и символьного выполнения.
В первой главе рассматриваются существующие методы верификации программного обеспечения, их достоинства, недостатки и применимость. В сравнении приводятся функциональный и структурный подходы к тестированию программ.
Вторая глава посвящена тестированию программ на основе граф – моделей. Приведены используемые в рамках структурного тестирования граф-модели программ, основанные на них критерии полноты тестирования и методы выбора тестовых путей и тестовых воздействие, особое внимание уделено минимальным покрытиям управляющим графам и их использованию с целью выбора минимально грубого множества тестов.
В третьей главе рассматривается проблема определения полноты тестирования на различных его этапах – как при тестировании на этапе разработки, так и при верификационном тестировании. Приводятся существующие подходы к оценке полноты тестирования, основанные на инструментировании тестируемой программной системы.
В четвертой главе рассматриваются технические аспекты автоматизации тестирования – состав систем автоматизации, методы выбора тестовых воздействий.
В пятой и шестой главах рассматривается авторский подход к автоматизации модульного и дизайн-тестирования программных систем, основанный на алгебраической модели программы и динамическом символьном выполнении.
Книга предназначена для студентов направления «Информатика и вычислительная техника», магистрантов, обучающихся по программе «Диагностические и информационно-поисковые системы», аспирантов и специалистов в области разработки и обеспечения качества программного обеспечения.