«В.В. Липаев ТЕСТИРОВАНИЕ КОМПОНЕНТОВ И КОМПЛЕКСОВ ПРОГРАММ УЧЕБНИК СИНТЕГ® Москва - 2010 УДК 004.41(075.8) ББК 32.973.26-018я73 Л61 Липаев В.В. Тестирование компонентов и комплексов программ. Учебник. – М.: СИНТЕГ, ...»
Надежная информация трассируемости облегчает соответствующее внесение изменений в ходе сопровождения, что повышает производительность разработчиков при модификации комплекса программ. Информацией трассируемости целесообразно пользоваться при сертификации продукта с особыми требованиями к надежности и безопасности, чтобы продемонстрировать, что все требования были реализованы, хотя это не доказывает, что они реализованы корректно и полностью. Естественно, если требования некорректны или В.В. Липаев. Тестирование компонентов и комплексов программ отсутствуют ключевые требования, то результаты трассируемости не помогут. Документирование взаимосвязей компонентов уменьшает риск возникновения проблем, если вдруг ключевой член команды, обладающей важной информацией о системе, покидает проект. Перечисленные достоинства трассирования требований сложных комплексов программ относятся к долгосрочным выгодам, которые снижают общую стоимость жизненного цикла программного комплекса, хотя при этом увеличиваются затраты на сбор и управление информацией трассируемости.
Отношения трассировки между компонентами проекта могут быть явными или неявными. Явная трассировка связь или отношение, между функцией комплекса и компонентом, осуществляющим поддержку этой функции, которая определяется исключительно решением специалиста о том, что такое отношение имеет смысл. Методология разработки и структура системы могут определять неявные отношения трассировки «дочерних» требований между компонентами и «родительскими» требованиями, когда существуют формальные, иерархические отношения. Связи трассируемости помогают отслеживать родительские требования, взаимосвязи и зависимости между отдельными требованиями. Эта информация отражает влияние изменения, если отдельное требование удаляется или модифицируется.
Удобный способ представления связей между требованиями и другими компонентами системы матрица трассируемости требований. Каждое функциональное требование в такой матрице связано с определенным вариантом использования (в направлении «назад»), и с одним или более элементами верификации и тестирования (в направлении «вперед»). Можно добавить дополнительные столбцы для расширения ссылок на другие рабочие продукты, например, на документацию системы. После того как с помощью инструментального средства заданы все известные отношения между компонентами, обязательным действием является проверка матрицы трассировки взаимосвязей компонентов на наличие следующих двух возможных индикаторов дефектов или ошибок.
Если при просмотре некой строки матрицы связей не удается обнаружить никаких отношений трассировки, вероятно, что еще не определено требование к программному компоненту, отвечающее функции исходного документа требований. Тем не менее, пустые Лекция 1.7. Верификация, трассирование и обеспечение баланса… строки являются индикаторами возможных ошибок и нуждаются в тщательной проверке. Современные средства управления требованиями должны предоставлять возможность автоматизированного проведения такой проверки.
Если в некотором столбце не оказывается отмеченных отношений трассировки, вероятно, было создано требование к программному компоненту, для которого нет требующей его функции продукта. Это может указывать на неправильное понимание роли программного требования, недостаток исходного документа проекта, а также на то, что компонент программы неправильный, не соответствует системному требованию или является дефектом разработчика, и в таком случае его следует удалить. Средство разработки комплекса программ должно обеспечивать возможность производить опрос заданных отношений трассировки, а также запоминать эти запросы и вызывать их впоследствии. Трассирование требований нельзя полностью автоматизировать, поскольку многие данные об источниках связей хранятся в головах разработчиков.
Нефункциональные требования, такие, как задачи по оценке архитектуры и некоторые атрибуты качества не всегда прослеживаются напрямую до компонентов и программного кода модулей.
Требование к времени отклика может диктовать выбор определенного оборудования, алгоритмов, структур баз данных или архитектуры комплекса программ. Требования к целостности для аутентификации пользователей активизируют создание производных функциональных требований, которые реализуются, с помощью, паролей.
В этих случаях следует трассировать соответствующие функциональные требования в обратном направлении, к их родительским нефункциональным требованиям, и, в прямом, до готового продукта.
Чтобы обнаружить пропущенные отношения, надо искать строки матрицы трассировки, которые показывают, что некая функция не связана ни с одним программным требованием (прецедентом). При обнаружении пропуска в отношениях нужно вернуться к исходному набору требований к комплексу программ и связанным с ними программным требованиям:
может оказаться, что связь была случайно пропущена при задании трассировки, в этом случае простое добавление новой связи и пересчет матрицы трассировки решать проблему;
может выясниться, что при разработке программных требоВ.В. Липаев. Тестирование компонентов и комплексов программ ваний просто не удалось учесть потребности одной из необходимых функций продукта, в этом случае следует исправить проект и добавить подходящие требования.
Обеспечение баланса требований к качеству комплексов Поэтапная разработка спецификаций требований к комплексам программ обычно выполняется итерационно после первичной оценки масштаба проекта и обусловленных такими оценками рисков вследствие ошибок его размера в большую или меньшую сторону. Ограничения при прогнозировании требований определяются, прежде всего, имеющимися данными о прототипах, которые могут быть использованы в качестве исходных аналогов или обобщенных характеристик. В общем случае для оценки, прогнозирования и обоснования равновесия требований новой или модификации версии программного комплекса необходимы исходные данные:
обобщенные характеристики использованных ресурсов и технико-экономические показатели завершенных разработок прототипов программного комплекса, а также оценки влияния на них различных факторов объекта и среды разработки;
реализованные планы и обобщенные перечни выполненных работ, реальные графики проведенных ранее оценок и разработок различных программных комплексов;
цели и содержание частных работ в процессе создания предыдущих сложных комплексов программ и требования к их выполнению для обеспечения необходимого качества в целом и минимальных рисков;
структура и содержание документов, являвшихся результатом выполнения ранее отдельных работ.
Для устранения или снижения рисков до допустимых пределов может быть необходимо изменение требований к функциональной пригодности и/или к характеристикам качества и доступным ресурсам (см. лекцию 1.3). Поэтому на этапах проектирования последовательно должны определяться:
при проектировании концепции и первичной оценке масштаба проекта предварительные требования к назначению, функциональной пригодности и к номенклатуре необходимых характеристик качества программного комплекса;
Лекция 1.7. Верификация, трассирование и обеспечение баланса… при предварительном проектировании уточненная оценка масштаба проекта, требования к функциональным и конструктивным характеристикам качества с учетом общих ограничений ресурсов, перечень источников угроз и величины возможных рисков;
при детальном проектировании подробные спецификации требований к функциональным и конструктивным характеристикам качества с детальным учетом и распределением реальных ограниченных ресурсов, а также интегральные риски при их оптимизация по критерию качество/затраты.
Этап разработки Концепции проекта целесообразно начинать с формализации и обоснования набора исходных требований, отражающих общие особенности класса, назначения и функции комплекса программ, потребителей и этапов жизненного цикла проекта, каждый из которых влияет на выбор определенных характеристик программного комплекса. Для этого первоначально целесообразно использовать номенклатуру функциональных характеристик и качества, стандартизированных в документе ISO 9126. Их описания желательно предварительно упорядочивать по приоритетам с учетом особенностей назначения и сферы применения конкретного программного комплекса.
На этапе создания концепции и системного анализа формируются цели разработки проекта, выбираются методы и алгоритмы решения основных, функциональных задач, а также формулируются предварительные требования и критерии качества создаваемых компонентов. При этом, естественно, встает вопрос о ресурсах, которые потребуются для достижения целей и о возможности их реализации. Для обеспечения рациональной достоверности первичное прогнозирование целесообразно проводить путем экстраполяции на базе накопленных конкретных данных об отдельных аналогичных предшествующих разработках или с использованием совокупности подобных разработок, проведенных на данном предприятии.
До завершения разработки первичного технического задания на комплекс программ могут быть сформулированы только приближенные исходные требования, отражающие объект разработки и условия его создания. Тем не менее, экспертный опрос ведущих специалистов позволяет составить первичный проект требований, сценарий или модель продукта, масштаб и условий разработки. Достаточно достоверное прогнозирование требований, реВ.В. Липаев. Тестирование компонентов и комплексов программ сурсов и длительности разработки комплекса программ возможно только при последующем применении жестко регламентированной технологии. После разработки проекта технического задания в процессе структурного проектирования и распределения ресурсов ЭВМ, размер комплекса программ и используемой памяти определяется с точностью 20 30%, что позволяет значительно повысить достоверность прогнозирования общих затрат и их составляющих.
После выбора технологии, средств автоматизации разработки и технологических ЭВМ появляется возможность более достоверно учесть эти исходные данные для подготовки уточненного сценария разработки. Регистрация этих данных может служить дополнительным ориентиром для оценки полных ресурсов на разработку и возможных рисков.
Разработку и утверждение спецификаций требований к функциональным характеристикам и качеству комплекса программ с учетом анализа рисков целесообразно проводить итерационно на этапах предварительного и детального проектировании. Для критических и особо сложных проектов необходим детальный анализ факторов и рисков при разработке сбалансированных требований и их оптимизация по критерию качество/затраты. При этом могут применяться два критерия:
максимизация функциональной пригодности при применении программного комплекса путем варьирования характеристик качества при заданных ограничениях на использование ресурсов и допустимых рисках;
минимизация риска – ущерба от не полного выполнения требуемой функциональной пригодности и некоторых характеристик качества вследствие недостаточных ресурсов и/или низких характеристиках комплекса программ.
Эти критерии целесообразно применять последовательно, итерационно на каждом из основных этапов проектирования комплекса программ. При первоначальном определении требований к функциональной пригодности и к характеристикам качества заданные заказчиком ограничения ресурсов не всегда могут учитывать ряд особенностей проекта, что обусловит недопустимое снижение (или завышение) требований к некоторым характеристикам или рискам. Кроме того, возможно, что некоторые характеристики противоречивы или принципиально нереализуемы в данном проекте. В результате не Лекция 1.7. Верификация, трассирование и обеспечение баланса… сбалансированные требования и доступные ресурсы проявятся как риски – ущерб в виде потерь в качестве или в потребности дополнительных ресурсов. После определения назначения и функций комплекса подготовка исходных данных и концепции проекта должны завершаться выделением номенклатуры приоритетных характеристик, имеющих достаточно сильное влияние на функциональную пригодность и сокращающих риски комплекса программ.
На этапе предварительного проектирования после фиксирования исходных данных конкретного проекта начинаются выбор требований к его свойствам, а также установление и утверждение конкретных характеристик качества и допустимых рисков, которые могут быть взаимосвязаны. Такой анализ должны проводить заказчик, менеджер проекта и некоторые потенциальные пользователи совместно со специалистами, обеспечивающими ЖЦ комплекса программ и реализацию установленных требований к показателям качества. Для показателей, представляемых качественными свойствами и признаками их наличия, желательно определить и зафиксировать в спецификациях описания допустимых условий и рисков, при которых следует считать, что данная характеристика может или должна быть реализована в проекте. Требования к значениям характеристик должны быть предварительно проверены разработчиками на их реализуемость с учетом доступных ресурсов конкретного проекта и при необходимости откорректированы по составу и значениям с учетом допустимых рисков. При ограниченности ресурсов проекта распределение приоритетов должно становиться более строгим и могут снижаться приоритеты характеристик, для реализации которых ресурсов недостаточно. В результате формируется полный набор требуемых функциональных и конструктивных характеристик, свойств и допустимых рисков в жизненном цикле комплекса программ.
В зависимости от сложности проекта окончательным результатом работ при предварительном или детальном проектировании должны быть детализированные и утвержденные требования к номенклатуре, свойствам и значениям качества и допустимым рискам проекта, которые достаточны для его полноценного рабочего проектирования и последующей эффективной эксплуатации программного комплекса. Эти требования закрепляются в контракте и техническом задании, по которым разработчик впоследствии должен отчитываться перед заказчиком при завершении проекта. Однако на поВ.В. Липаев. Тестирование компонентов и комплексов программ следующих этапах жизненного цикла и при конфигурационном управлении требования могут изменяться по согласованию между заказчиком и разработчиком, которые чаще всего приурочиваются к подготовке новой версии программного продукта. Для этого необходим мониторинг масштаба проекта, требований и реализаций характеристик и рисков в течение всего жизненного цикла комплекса программ.
При детальном проектировании может быть целесообразно дополнительное уточнение совокупности выбранных функциональных характеристик и качества сложных программных комплексов с учетом рисков, а также соотношения качества и затрат ресурсов. Для обобщенного оценивания качества программного комплекса необходим учет относительного влияния и риска каждой конструктивной характеристики на функциональную пригодность. При этом не всегда учитываются ресурсы для их реализации в конкретном комплексе.
Это часто приводит к выдвижению ряда не рациональных требований, которые значительно отличаются либо по степени влияния на функциональную пригодность, либо по величине ресурсов, необходимых для их реализации.
Для целенаправленного эффективного управления рисками комплекса программ при детальном проектировании желательно иметь механизм объединения разнородных характеристик в некоторый интегральный показатель, отражающий их совокупное влияние на его функциональную пригодность. Таким образом, при разработке требований выявилась проблема анализа системной эффективности программного комплекса и обобщения его характеристик, а также оценивания совместного их влияния на функциональную пригодность с учетом затрат на их реализацию.
Для управления рисками и детального сопоставительного оценивания выбранных характеристик качества целесообразно каждой из них присваивать коэффициент или приоритет влияния на функциональную пригодность. Эти приоритеты могут формироваться формализованным экспертным анализом и детальным установлением влияния каждого атрибута качества на функциональную пригодность с учетом относительных затрат на реализацию соответствующего атрибута. Для этого группа квалифицированных экспертов из состава заказчиков, потенциальных пользователей и/или разработчиков должны оценивать и устанавливать значения таких коэффициентов – Лекция 1.7. Верификация, трассирование и обеспечение баланса… рисков (приоритетов) в пределах унифицированной шкал (например, 1–10). Аналогично, по такой же шкале экспертами целесообразно оценивать относительные затраты ресурсов, которые следует выделять на реализацию сокращения рисков. Для каждого вида рисков отношение коэффициента влияния на функциональную пригодность к относительным затратам на его достижение можно рассматривать как обобщенный уровень приоритета требований к этому сокращению риска.
Для конкретного комплекса программ состав и значения приоритетов следует поэтапно адаптировать и уточнять с учетом их назначения и функций. Наивысший приоритет (10) следует интерпретировать как обязательное выполнение разработчиком соответствующего требования к указанному свойству или атрибуту качества с отсутствием риска. Низшее значение приоритета (1) означает, что данный малый риск может не учитываться в данном проекте. Промежуточные значения приоритетов должны отражать относительное влияние соответствующих атрибутов на функциональную пригодность и ее качественные свойства с учетом доступных ресурсов на их реализацию. При этом возможно, что некоторые требования к атрибутам качества при их низких приоритетах могут не полностью реализоваться в реальном комплексе программ. Это дает возможность разработчикам творчески подходить к требованиям заказчика при реализации жизненного цикла комплекса программ в условиях ограниченных ресурсов. Для последовательного оценивания обобщенных приоритетов при управлении рисками и корректировке атрибутов качества конкретного проекта комплекса программ целесообразно проводить экспертную оценку коэффициента влияния требуемой характеристики качества на функциональную пригодность и экспертную оценку относительных затрат ресурсов на реализацию требуемых значений качества без рисков.
При проектировании может быть полезно последовательно уточнять и выравнивать риски требований к каждому свойству и атрибуту качества программного комплекса. Для сложных комплексов программ при уточнении требований к качеству при детальном проектировании целесообразно использовать оценку относительного коэффициента влияния характеристик на функциональную пригодность с учетом затрат на ее реализацию – обобщенный уровень приоритета. При этом набор значений обобщенных уровней приоритеВ.В. Липаев. Тестирование компонентов и комплексов программ тов для выбранных атрибутов качества конкретного программного продукта можно разделить, например, на три группы:
доминирующие характеристики качества и риски, оказывающие наибольшее влияние на функциональную пригодность при допустимых затратах (обобщенный приоритет > 8);
значения характеристик качества и рисков, имеющие достаточное влияние на функциональную пригодность и значительные затраты на реализацию (обобщенный приоритет < 7, но > 4);
характеристики качества, значения требований к которым не соответствуют их влиянию на функциональную пригодность и/или затратам на реализацию и могут не учитываться (обобщенный приоритет < 3).
Эти данные могут использоваться, прежде всего, как ориентиры для селекции и исключения из требований характеристик качества с особенно низкими обобщенными приоритетами рисков, в наименьшей степени влияющих на функциональную пригодность программного продукта и не оправдывающих больших затрат на реализацию.
Анализ оставшихся характеристик качества и рисков может проводиться для выделения завышенных требований, а также, возможно, для снижения их значений и приближения их влияния к средним значениям. Кроме того, сравнительный анализ баланса обобщенных приоритетов на основе отношения влияния на качество и затраты позволяет выделять атрибуты качества, отличающиеся большими затратами – рисками, не оправданными их степенью воздействия на функциональную пригодность. Подобные процедуры могут завершать разработку требований к свойствам, характеристикам качества и рискам при детальном проектировании сложных программных комплексов.
Выше анализировалось и оценивалось преимущественно изменение функциональной пригодности и снижение риска при совершенствовании характеристик качества комплексов программ. Однако для заказчика и пользователей доминирующее значение могут иметь номенклатура и особенности реализации некоторых основных функций комплекса программ, которые, как правило, требуют наибольших затрат и определяют основной эффект и риски от применения программного продукта, а также потенциальный уровень спроса на рынке. Если затраты на разработку можно оценивать и прогнозировать с некоторой достоверностью, то эффективность применения и Лекция 1.7. Верификация, трассирование и обеспечение баланса… особенно будущий спрос на конкретный комплекс программ со стороны пользователей априори оценить трудно. Такие оценки могут проводиться на основе дополнительных маркетинговых исследований и опыта эксплуатации аналогичных комплексов программ или достаточно близких их прототипов.
В.В. Липаев. Тестирование компонентов и комплексов программ
ТЕСТИРОВАНИЕ МОДУЛЕЙ, КОМПОНЕНТОВ И
КОМПЛЕКСОВ ПРОГРАММ
ТЕСТИРОВАНИЕ ПОТОКОВ УПРАВЛЕНИЯ
ПРОГРАММНЫХ МОДУЛЕЙ И КОМПОНЕНТОВ
Стратегии выбора тестов для программных модулей Программные модули являются наиболее массовым компонентом в сложных комплексах программ и требуют для тестирования суммарно наибольших затрат. Затраты на тестирование каждого модуля прямо пропорциональны сложности, которая зависит от его структуры, числа узлов и объема необходимых вычислений. Суммарные затраты на тестирование каждого модуля можно оценить по значению сложности его графа. Некоторые модули на практике могут оказаться недостаточно протестированными из-за их высокой сложности и необходимости больших затрат, которые быстро возрастают (почти квадратично) при увеличении числа узлов и всегда ограничены. Уровень сложности модулей и полнота их тестирования определяют качество функционирования групп и комплекса программ в целом. Наиболее сложные и большого размера модули труднее тестировать и в них наиболее вероятны дефекты и ошибки. Ограниченность ресурсов на тестирование программных модулей приводит к целесообразности по возможности сокращать их сложность, выравнивать при проектировании их размеры и выделять затраты на их проверку в соответствии со сложностью каждого модуля. Особенно сложные модули полезно делить на более мелкие и простые и так перестраивать их структуру, чтобы сокращалось суммарное число маршрутов в каждом модуле и их размер – рис. 2.1.Относительная простота программных компонентов и модулей (ПМ) позволяет детально анализировать их внутреннюю структуру и маршруты исполнения программы. Это обеспечивает возможность Лекция 2.1. Тестирование потоков управления программных модулей… реализации двух стратегий тестирования: от структуры и от данных. Этим двум стратегиям соответствуют два метода тестирования программ: метод анализа потоков управления и анализа потоков данных. Методы дополняют друг друга, и каждый может быть доминирующим на начальных этапах отладки в зависимости от типа объекта и условий тестирования.
Тестирование потоков управления программных - стратегии выбора тестов для программных модулей и компонентов:
учет особенностей тестирования потоков управления и потоков данных модулей;
критерии выделения маршрутов тестирования потоков стратегия упорядочивания маршрутов тестирования потоков управления модулей;
планирование тестирования программных модулей;
- анализ сложности тестирования ациклических программных структурной сложности программных модулей;
оценки трудоемкости тестирования программных - оценки сложности тестирования программных модулей, содержащих циклы;
- оценки сложности тестирования модулей в программных компонентах;
- оценка корректности результатов тестирования модулей;
- примеры сложности тестирования программных модулей:
оценки сложности тестирования элементарных структур оценки сложности тестирования модулей при различных критериях выделения маршрутов.
Тестирование потоков управления в структуре модуля программы должно быть начальным этапом, так как при некорректной структуре модуля возможны наиболее грубые искажения выходных результатов и даже отсутствие некоторых из них. Оно состоит в проверке корректности последовательностей передач управления и форВ.В. Липаев. Тестирование компонентов и комплексов программ мирования маршрутов исполнения модулей комплекса программ при обработке тестов. Для тестирования корректировок структуры модулей программ в большинстве случаев требуются относительно меньшие затраты по сравнению с тестированием потоков данных. При первой стратегии (рис.2.2) за основу принимается структура ПМ, построенная по тексту программы в виде графа. В графе программы по некоторым критериям выделяются и упорядочиваются маршруты исполнения программы и условия предикаты, при которых они могут быть реализованы. Эти узлы условия используются для подготовки тестовых наборов, каждый из которых должен реализоваться по маршруту, принятому за эталон при подготовке теста. Отклонение процесса исполнения теста от первоначально выбранного маршрута рассматривается как ошибка, причина которой может быть либо в первичной структуре ПМ, либо в реализации конкретного маршрута при заданном тесте на входе.
После устранения ошибок и несоответствия выбранных и реализованных маршрутов потока управления для каждого из них может проверяться процесс обработки данных и выявляться ошибки в результатах их преобразования. Затем оценивается достаточность выполненного тестирования по степени покрытия исходного графа программы проверенными маршрутами, которые выделялись по выбранному или заданному критерию. Завершается тестирование при требуемом покрытии графа программы протестированными маршрутами или при использовании ресурсов, выделенных на тестирование.
В последнем случае необходима оценка достигнутой корректности программы и регистрация этой величины.
При этой стратегии некоторые выделяемые маршруты могут оказаться принципиально нереализуемыми из-за противоречивых условий в последовательных операторах узлах графа программы.
Вследствие этого для некоторых модулей могут подготавливаться тесты, которые являются избыточными и не отражают реальное функционирование программы. Тем не менее, данная стратегия имеет преимущества при тестировании логических программ с малой долей вычислений. При этом достаточно эффективно контролируется полнота тестирования при различных критериях выделения маршрутов и методах их упорядочения.
Лекция 2.1. Тестирование потоков управления программных модулей… В.В. Липаев. Тестирование компонентов и комплексов программ При второй стратегии (см. рис. 2.2) за основу принимаются требования спецификаций, конкретные тестовые и эталонные значения расчетов, которые подготавливаются специалистами путем анализа переменных, констант и предикатов в тексте программы. При каждом тесте программа исполняется по определенному маршруту, который регистрируется. При этом реализованный в соответствии с анализируемыми требованиями маршрут и поток данных рассматриваются как эталонные компоненты структуры программы. По мере тестирования отмечаются проверенные операторы и оценивается полнота покрытия тестами требований спецификаций и данных на маршрутах тестирования. Накопление и обобщение реализованных маршрутов позволяет воспроизвести структуру программы и контролировать степень покрытия каждого компонента. Для этого на каждом этапе тестирования выделяются компоненты программы, оставшиеся непроверенными, для которых необходимо подготавливать дополнительные тесты. Однако при такой стратегии трудно оценить степень покрытия и проверки всех маршрутов исполнения программы без использования структурного графа, построенного по ее исходному тексту.
Данная стратегия имеет преимущества при сравнительно простой структуре программы и при преобладании в ней вычислительных операторов с множеством переменных и констант. На каждом маршруте упорядоченное варьирование переменных акцентирует внимание на вычислительной части программы, что существенно для такого класса ПМ. Однако возрастает риск пропустить сочетания предикатов, определяющих непроверенный маршрут. Поэтому практически всегда целесообразно совместное применение двух стратегий с акцентом на одну из них в зависимости от особенностей тестируемого ПМ или его частей. Программы с преобладанием сложной логической структуры и с относительно малой вычислительной частью целесообразно начинать тестировать по первой стратегии и только для маршрутов с вычислительными операторами использовать анализ потоков данных (вторую стратегию). В модулях, имеющих простую структуру и содержащих значительный объем вычислений после первичной отладки по второй стратегии, целесообразна проверка полноты тестирования структуры и завершение отладки по первой стратегии.
Лекция 2.1. Тестирование потоков управления программных модулей… Известно, что исчерпывающее тестирование, гарантирующее полное отсутствие дефектов и ошибок, принципиально не возможно и число дефектов, обнаруживаемых в программах даже независимыми испытателями, имеет пределы. Реальные ограничения доступных ресурсов определяют количество не устраненных дефектов и достижимую корректность компонентов и комплекса в целом. На практике учитывать степень покрытия тестами достаточно трудоемко и зачастую желательно иметь более простой способ регламентирования и оценивания качества тестирования. Возникает проблема, как практически учесть ограничения ресурсов и когда прекратить верификацию и тестирование, а также какая при этом будет достигнута корректность программ, и способна ли она удовлетворить заказчика и пользователя при эксплуатации программного продукта.
В качестве исходной информации при тестировании структуры программ используется схема связей между операторами текста программы. По этой схеме может выделяться полный набор маршрутов исполнения программы, подлежащих тестированию. Для каждого выделенного маршрута по тексту программы формируется набор условий, определяющих его реализацию и используемый при создании соответствующего теста. Детерминированное тестирование структуры программных модулей имеет целью проверку корректности выделенных маршрутов исполнения программ и обнаружение в основном логических ошибок формирования маршрутов. На практике при отсутствии упорядоченного анализа потоков управления некоторые маршруты в программе (до 50%) оказываются пропущенными при тестировании. Поэтому первая задача, которая решается при тестировании структуры программ, – это получение информации о полной совокупности реальных маршрутов исполнения в каждой программе. Такое представление маршрутов позволяет упорядоченно контролировать достигнутую степень проверки маршрутов и в некоторой степени предохраняет от случайного пропуска отдельных пропущенных маршрутов. В результате значительно повышается достигаемое качество программных компонентов, и тестирование приобретает планируемый систематический характер.
Анализ критериев тестирования и выделение тестируемых маршрутов удобно проводить, используя графовые модели программ.
При планировании тестирования структуры программ возникают, прежде всего, две задачи: формирование критериев выделения марВ.В. Липаев. Тестирование компонентов и комплексов программ шрутов для тестирования ПМ и выбор стратегий упорядочения выделенных маршрутов.
Критерии выделения маршрутов для тестирования соответствуют критериям определения структурной сложности программных модулей. В основном используются критерии:
покрытия графа программы минимальным количеством маршрутов, охватывающих каждый узел или связь графа хотя бы один раз – f1;
выделения линейно-независимых маршрутов на базе понятия цикломатического числа; каждый маршрут отличается от всех других хотя бы одной связью (или одним узлом) – f2.
Число маршрутов, выделяемых по этим критериям, зависит от структуры программы. В реальных программах часть маршрутов может быть нереализуемой из-за противоречий в условиях, анализируемых на последовательных участках маршрута. Это может приводить к сокращению числа маршрутов по любому критерию. Невыполнение правил структурного построения программ, наоборот, может приводить к возрастанию числа маршрутов. К значительному возрастанию числа маршрутов обычно приводят циклы в программах. Несмотря на перечисленные обстоятельства, приведенные критерии являются достаточно удобными для практических оценок сложности и полноты тестирования структуры программ. Планировать тестирование можно по одному из критериев или используя последовательно более жесткие критерии выделения маршрутов, при которых соответственно возрастает объем и сложность тестирования.
Граф потока управления и/или граф потока данных приведет к различным тестам, и при таком подходе не будет значительного перекрытия созданных тестов. Если поместить граф потока управления внутрь графа потока данных, выявятся повторяющиеся процедуры, большей частью определяемые потоками данных. Если расположите часть, представляемую потоками данных, внутри потока управления, тестовый вариант использует графы потока управления и потока данных.
Стратегии упорядочения маршрутов могут учитывать сложность маршрута и тестов для его проверки (количество узлов в графе, операторов, условных переходов и циклов в маршруте, частость его исполнения при рабочем функционировании ПМ, сложность получения соответствующих эталонных данных и другие факторы). В первую очередь, целесообразно производить проверку основной группы Лекция 2.1. Тестирование потоков управления программных модулей… маршрутов с экстремальными значениями используемого критерия в пределах ресурсов, выделенных для тестирования. При имеющихся ограничениях некоторая часть маршрутов может оказаться не проверенной и характеризует достигнутую корректность данной программной компоненты по выбранному критерию.
Упорядочение маршрутов при планировании тестирования в ПМ может базироваться на использовании в основном трех характеристик программных модулей (компонентов):
числа узлов (или связей), операторов в выделенных маршрутах или расчетной длительности их реализации (стратегия 1);
числа узлов – альтернатив или условных переходов, определяющих формирование каждого маршрута (стратегия 2);
вероятности исполнения реализуемых маршрутов при реальном функционировании программы (стратегия 3).
Эти стратегии тестирования позволяют сосредоточить внимание разработчика на анализе наиболее важных элементов ПМ. При стратегии 1 первичному тестированию подлежат маршруты, наиболее длинные по числу операторов (узлов в графе) и по времени исполнения. Им соответствуют обычно маршруты с наибольшим объемом вычислений и преобразований переменных. Эта стратегия целесообразна при планировании тестирования программ, имеющих вычислительный характер обработки данных при небольшом числе логических условий и маршрутов исполнения программ. Выбранные первичные маршруты не обязательно являются наиболее сложными по логике функционирования.
При стратегии 2 приоритет отдается маршрутам, наиболее сложным по числу анализируемых условий – альтернатив. Такая стратегия предпочтительна при тестировании логических программ с небольшим объемом вычислений. При обеих стратегиях на завершающие этапы тестирования остаются простые по вычислениям или по логике исполнения маршруты, для которых необходимы относительно короткие тесты. Это соответствует традиционной стратегии многих тестировщиков программ подготавливать вначале тесты с возможно большим охватом элементов тестируемой программы.
В типичной программе на долю 3% операторов зачастую приходится до 50% времени исполнения всей программы. В результате изучения профиля программы могут быть выявлены наиболее критические по длительности или самые частые маршруты исполнения ПМ. Использование профиля программ позволяет сконцентрировать В.В. Липаев. Тестирование компонентов и комплексов программ усилия разработчиков ПМ на проверке наиболее активно функционирующих элементах и выделить слабо проверенные части программ, которые исполняются редко.
Планирование тестирования структуры программных модулей в значительной степени может быть автоматизировано. Задача автоматизированных систем планирования тестирования состоит в выделении маршрутов программ по одному или нескольким критериям с последующим упорядочением по заданной стратегии. В результате тестировщик программы автоматизировано информируется о составе маршрутов в программе для проведения упорядоченного тестирования. Кроме того, если фиксировать маршруты, по которым уже проведено тестирование, то их можно автоматически исключать из информирования и выдавать на регистрацию только группу маршрутов, подлежащих первоочередной проверке. Эти же данные могут использоваться для автоматического расчета полноты проверки и для оценки достигнутой корректности программы по каждому из критериев выбора маршрутов.
При анализе сложности тестирования межмодульных связей по управлению и по информации следует учитывать, что тестирование каждой информационной связи обычно необходимо при нескольких значениях каждой переменной, что соответственно увеличивает затраты. Оценка относительной сложности тестирования групп программ способствует правильному распределению ресурсов (машинного времени, труда специалистов и т.д.), выделяемых на тестирование групп компонентов разной сложности. Кроме того, такие оценки стимулируют более полное тестирование ПМ, так как обнаружение и локализация каждой ошибки в группе программ на порядок дороже, чем в автономном модуле.
Сложность тестирования ациклических программных Сложность программы определяется числом взаимодействуюих элементов – узлов, числом связей между узлами и сложностью их взаимодействия. При функционировании программы разнообразие ее поведения и разнообразие входных и результирующих данных в значительной степени определяются набором путей – маршрутов, по которым исполняется программа. Экспериментально установлено, что сложность (трудоемкость) тестирования программного модуля Лекция 2.1. Тестирование потоков управления программных модулей… зависит не столько от размера текста программы (числа операторов, узлов или связей графов), сколько от числа отдельных путей ее исполнения, существующих в программе. Все маршруты исполнения программы модуля и возможной обработки данных должны быть проверены при создании программы и тем самым определяют сложность ее полного тестирования (см. рис. 2.1).
Выше отмечалось, что маршруты исполнения программного модуля можно разделить на два вида: маршруты принятия логических решений и преобразования логических переменных (потоки управления) и маршруты исполнения преимущественно вычислительной части программы и преобразования переменных (потоки данных). Первый вид маршрутов является результатом функционирования схем принятия решений и преобразования логических переменных. Для логических переменных отсутствует сильная корреляционная связь между соседними значениями, и каждое изменение переменной может определять разные области пространства результирующих значений на выходе программы. Такое преобразование переменных обеспечивается алгоритмами со сложной логической струкурой, содержащей ряд проверок логических условий, циклов для поиска и селекции переменных, а также логические преобразования переменных. В результате в программе образуется множество узлов i маршрутов обработки исходных данных, которые определяют сложность структуры программы. В ряде случаев подтверждена достаточно высокая адекватность использования потока управления и структурной сложности программ для оценки трудоемкости тестирования или вероятности не выявленных ошибок и затрат на разработку программных модулей в целом. Сложность тестирования потоков управления в программных модулях можно оценивать по числу маршрутов – Mk, необходимых для их проверки, или более по суммарному числу условий – k (узлов в графе), которые необходимо задать в тестах для прохождения при тестировании всех маршрутов определенной k-й программы:
где i – число условий-предикатов, определяющих i-й маршрут.
Маршруты второго вида обычно логически короче, чем первого, и предназначены для преобразования величин, являющихся зачасВ.В. Липаев. Тестирование компонентов и комплексов программ тую результатами измерения некоторых физических характеристик (поток данных). Такие переменные могут быть связаны условиями гладкости, т.е. условиями малых изменений производных этих переменных по времени или по другим параметрам. При оценке сложности вычислительных маршрутов программ необходим учет числа операндов, участвующих в вычислениях. Кроме того, исходные и результирующие данные при тестировании должны принимать несколько значений. Во всем диапазоне исходных переменных следует выбирать несколько характерных точек (предельные значения и несколько промежуточных), при которых проверяется программа. В особых точках значений и сочетаний переменных и в точках разрыва функции необходимо планировать дополнительные проверки. Таким образом, сложность проверки k-го программного модуля – k будет определяться числом маршрутов – Mk исполнения программы и числом обрабатываемых операндов – li на каждом i маршруте, умноженном на число значений – ij для каждой исходной j-й величины на этом маршруте:
Расчет показателя сложности тестирования программного модуля по такой схеме имеет значительную неопределенность из-за выбора числа значений переменных и констант – ij (в основном особых точек и величин) при варьировании исходных и промежуточных значений потока данных. В то же время доля вычислительной части во многих сложных комплексах программ управления и обработки информации относительно невелика. Ее можно оценить из того, что ориентировочное число умножений и делений в таких программах в сумме составляет обычно 1 – 3%, а общее число арифметических операций не превышает 10%. Поэтому ниже большее внимание уделено анализу структурного тестирования модулей управляющих комплексов программ.
Структурная сложность программного модуля может быть рассчитана по числу маршрутов в программе – Mk и сложности каждого i-го маршрута – i. Эти показатели в совокупности определяют минимальную сложность тестов – k для проверки структуры программного модуля (1), а, следовательно, трудоемкость его тестироЛекция 2.1. Тестирование потоков управления программных модулей… вания и вероятность пропуска ошибки в программе. Выделение маршрутов исполнения программы, минимально необходимых для ее проверки, и оценка структурной сложности может осуществляться по различным критериям. При этом формирование маршрутов зависит не только от структуры программы, но и от значений переменных, на различных этапах обработки. Затраты на тестирование каждого модуля ориентировочно прямо пропорциональны сложности, которая зависит от его структуры и объема вычислений. При тестировании k-го программного модуля необходимо задать и проанализировать число значений параметров тестов:
Суммарные затраты на тестирование модуля Ck пропорциональны значению его сложности и ориентировочно можно определить выражением:
Значение множителя трудоемкости тестирования маршрута – c зависит от степени автоматизации процесса тестирования и генерации тестов. В высокоавтоматизированных системах тестирования сокращаются затраты ручного труда на подготовку и анализ тестовых данных, однако увеличиваются затраты на машинное время, необходимое для генерации тестов и для автоматической обработки результатов тестирования. В зависимости от этих факторов значения коэффициента – c могут различаться в несколько раз, и их следует экспериментально определять для каждой системы автоматизации тестирования.
Для определения суммарных затрат на тестирование модуля необходима оценка вероятности пропуска ошибки в модуле, т.е. достигаемого качества тестирования при принятом критерии выбора маршрутов исполнения программы и числа значений каждой переменной для выбранного маршрута. Обычно устанавливаются некоторые правила выделения маршрутов и варьирования переменных, гарантиВ.В. Липаев. Тестирование компонентов и комплексов программ рующие достаточно глубокое тестирование модулей при доступных ограниченных ресурсах. Эти правила можно выбирать эмпирически по опыту аналогичных разработок и стандартизировать для определенного предприятия или проекта. Такое выделение маршрутов трудно формализовать, и оно может представляться излишне трудоемким для оценки показателей сложности тестирования программ. Поэтому, зачастую, используются простые критерии выделения маршрутов, учитывающие только потоки управления и структурные характеристики программных модулей, а сложные вычислительные элементы программных модулей выделяются в подграфы и тестируются автономно.
Сложность тестирования модулей, содержащих циклы Наличие циклов в программе способно резко увеличивать сложность (и трудоемкость) их тестирования. Полное тестирование должно охватывать проверку каждого маршрута в цикле при всех возможных итерациях цикла и при всех сочетаниях циклов с маршрутами ациклической части программы. При возрастании любого из сомножителей (числа независимых ациклических маршрутов, проходящих через цикл, числа внутренних маршрутов тела цикла или числа его итераций) пропорционально растет их произведение, а, следовательно, и сложность тестирования. Поэтому исчерпывающее тестирование реальных сложных программ с циклами практически невозможно (см. рис. 2.1).
В качестве критериев при оценивании сложности тестирования структуры программы с циклами можно использовать два выше подробно описанных критерия: число маршрутов М, выделяемых по критериям f1 или f2 ; суммарную сложность тестирования, т.е. суммарное число узлов ветвления на всех выделенных маршрутах, соответствующее числу условий, которое необходимо задать в тестах при выбранном критерии f1 или f2. В динамике реального исполнения простейшего цикла между его итерациями могут существовать зависимости, по крайней мере, трех видов:
на разных итерациях цикла исполняются независимо все возможные маршруты внутреннего тела цикла;
на всех итерациях цикла исполняется один и тот же маршрут тела цикла или некоторая определенная их последовательность;
Лекция 2.1. Тестирование потоков управления программных модулей… на разных итерациях цикла в силу наличия семантических связей исполняется подмножество реализуемых маршрутов тела цикла, зависящее от данных или от номера итерации.
При первой зависимости, которая встречается наиболее редко, возникает необходимость в полном переборе всех внутренних маршрутов тела цикла в сочетании с определенным числом итераций. В этом случае сложность тестирования цикла определяется сразу обоими параметрами: числом маршрутов тела цикла и числом итераций, и приближается к сложности исчерпывающего тестирования. При второй зависимости число маршрутов в теле цикла практически не влияет на сложность цикла. Определяющим становится количество итераций, необходимых для тестирования вычислений в теле цикла (например, с учетом требуемой точности). При третьей, наиболее распространенной зависимости, определяющим при оценке сложности тестирования является не число итераций цикла, а число маршрутов тела цикла. Простейшие оценки сложности циклических структур целесообразно проводить в предположении, что порядок реализации маршрутов тела цикла не зависит от номера итерации. В этом случае при оценке сложности циклических структур конструктивным является подход с позиции выбора минимально необходимого числа проверок итераций циклов.
Для оценки сложности структурного тестирования логических программ с простейшими циклами целесообразно уточнить критерии проверки сложности f1 и f2. По критерию f1 ациклическая часть программы покрывается минимальным числом маршрутов, в которые входят маршруты, проходящие через цикл, размыкающие его и образующие минимальное покрытие тела цикла. Кроме того, к покрытию добавляется маршрут, содержащий замыкающую дугу цикла.
По критерию f2 ациклическая часть программы проверяется количеством тестов, равным цикломатической сложности ациклической части программы. При этом к каждому такому маршруту присоединяются все примыкающие к нему циклы. Проверка каждого цикла осуществляется одним маршрутом, содержащим столько итераций, какова цикломатическая сложность тела цикла, а тело цикла покрывается линейно независимыми маршрутами.
При таких оценках определяющими факторами являются полнота проверки тела цикла, условий его замыкания и размыкания. При этих критериях сложность цикла наиболее просто оценить, представив его эквивалентным ациклическим подграфом (подграфами). НаВ.В. Липаев. Тестирование компонентов и комплексов программ пример, при критерии f2 эквивалентным циклу с одной точкой входа и одной точкой выхода будет линейный подграф, содержащий последовательно соединенные все линейно независимые маршруты тела цикла, связывающие его точку входа с точкой выхода. Такой эквивалентный ациклический подграф добавляется к каждому маршруту в покрытии ациклической части графа по критерию f2.
Эквивалентной циклу с одной точкой входа и одной точкой выхода при критерии f1 будет совокупность внутренних маршрутов, соединяющих точки входа и выхода и покрывающих тело цикла по этому критерию, а также маршрут, представляющий собой одну итерацию цикла, состоящую из его замыкающей дуги и маршрута из покрытия тела цикла. Совокупность этих маршрутов, объединенная в ациклический граф с общей точкой входа, будет в этом случае эквивалентным графом для всего цикла. Однако в этом случае к каждому из маршрутов в покрытии ациклической части графа программы по критерию f1 добавляется только один маршрут из части эквивалентного ациклического графа.
В качестве примера предположим, что число маршрутов в ациклической части программы равно М1. Тогда полное множество маршрутов состоит из полной совокупности всех маршрутов M1 в ациклической части программы и группы маршрутов тела цикла Mц, в которой к каждому маршруту M1 присоединено 1.2... итерации (витка) цикла, причем на каждой итерации выполняется, по крайней мере, один из внутренних маршрутов Mц тела цикла. Для графа, имеющего один цикл, требующего исполнения пяти итераций (витков) с тремя внутренними маршрутами, а также содержащего ациклических маршрутов, проходящих через цикл, суммарное число маршрутов для полного тестирования равно M* = (3х5)10 = 150. Такое число тестов трудно реализовать практически и приходится из них выбирать небольшое доступное число тестов, допуская возможные дефекты в не полностью проверенной части программы.
Для примера выявления типовых структур программ с циклами проанализированы 66 программных модулей, функционирующих в реальных системах управления. Анализ этой выборки показал, что в них отсутствуют циклы с числом выходов больше 3, а число циклов с тремя выходами составляет менее 10% от их общего числа. Число вложенных друг в друга циклов в среднем равно 2,2. Среднее число выходов из цикла составляет 1,4, среднее число операторов ветвЛекция 2.1. Тестирование потоков управления программных модулей… ления в теле цикла 4. Практически не встречаются сложные зацепляющиеся циклы, т.е. циклы, имеющие общие части, но не вложенные полностью друг в друга. Такие циклы особенно трудно тестировать, в первую очередь, в силу неопределенности значений переменных, влияющих на условия замыкания (размыкания) цикла. Применение зацепляющихся циклов при создании реальных программ, как правило, запрещают в методиках проектирования. В реальных программных модулях наиболее часто встречаются простейшие одиночные циклы с небольшим числом ( 2 – 5) ветвлений в теле цикла и одним выходом.
Для каждого реализуемого маршрута может быть необходимой проверка при нескольких прохождениях циклов и нескольких значениях каждой обрабатываемой переменной. Особенно важно проверять циклы с условным выходом на одном – двух, промежуточных, а также на максимальном и минимальном витках исполнения циклов.
В результате показатель сложности, число необходимых тестов и длительности проверки соответственно возрастают.
Разнообразие реальных циклических структур в программах сильно усложняет их анализ и получение достаточно общих характеристик сложности и достигаемой корректности тестирования. Для обобщенных оценок необходимо в конкретных проектах выделение классов типовых структур сочетания циклических и ациклических частей программ. При применении вложенных циклов со сложной структурой и с большим числом ветвлений в теле цикла сложность тестирования резко возрастает и велика вероятность сохранения в программе не обнаруженных дефектов и ошибок. Поэтому в процессе проектирования программных модулей необходимо в максимальной степени упрощать циклические компоненты в структуре, запрещать зацепляющиеся, вложенные и сложные структуры тела цикла, которые во многих случаях при тестировании определяют достигаемую корректность программных модулей.
Выше внимание акцентировалось на сложность тестирования автономных программных модулей. При тестировании модулей в составе компонентов необходимо учитывать их собственную сложность и межмодульных связей по управлению и по информации.
Каждый модуль, протестированный автономно, должен пройти дополнительное тестирование после включения в группу программ и в составе группы. Затраты на тестирование модулей в составе группы В.В. Липаев. Тестирование компонентов и комплексов программ программ должны учитывать относительные суммарные затраты на тестирование влияния взаимодействия в группе всех входящих модулей с коэффициентом dk 10 дает выражение = n2 3 (штриховая линия на рис. 2.4). Характерно, что увеличение числа вершин в 4 раза (от 32 до 128) для рассмотренных графов приводит к возрастанию структурной сложности более чем в 10 раз. Если же программу, имеющую 128 узлов, разделить на 4 модуля, то их суммарная сложность практически равна только учетверенной сложности модулей, содержащих по 32 вершины. Следовательно, для упрощения тестирования программ целесообразно ограничивать размеры программных модулей в пределах 10 – 20 узлов (около одной тысячи строк). Исследованные реальные программные модули систем управления в 80% случаев содержат не более 10 узлов и имеют структурную сложность < 50.
Примеры оценки сложности тестирования модулей при различных критериях выделения маршрутов. Приведенные выше выражения и критерии можно использовать для априорной оценки числа маршрутов и сложности тестирования графа программных модулей. Для планирования тестирования необходимо выявить зависимости этих характеристик от числа строк в программе модуля ее структуры и критериев выделения маршрутов в графе. Эту задачу можно решать экспериментально (или автоматизировано) путем подВ.В. Липаев. Тестирование компонентов и комплексов программ счета соответствующих характеристик в графах реальных программных модулей, используемых в различных классах комплексов программ. Ниже приводится пример такого расчета для среднего по сложности модуля. Расчеты могут быть автоматизированы, а их результаты обобщены по достаточно большой совокупности модулей комплексов программ определенного класса. Подобные статистические обобщения могут использоваться для ориентировки при проектировании и сложности тестирования ПМ. Для выявления общих зависимостей сложности тестирования программ целесообразно выделять типовые программные структуры модулей конкретного комплекса, а также такие, которые позволяют получить предельные (сверху и снизу) значения этих характеристик.
На рис. 2.5 представлен пример графа модуля программы, содержащий 14 вершин, 20 дуг и 3 цикла.
Такая программа сравнительно не высокой сложности содержит 100 – 200 строк ассемблера или около 30 строк на языке программирования высокого уровня и может рассматриваться как достаточно типичная. Для полной проверки модуля по первому критерию f1 достаточно четырех маршрутов. По этому критерию гарантируется проЛекция 2.1. Тестирование потоков управления программных модулей… верка всех передач управления между узлами графа программы и каждой связи узлов не менее одного раза. Самый длинный по количеству узлов последний маршрут не охватывает только 3 вершины из 14 и только 6 дуг из 20. После проверки трех последних маршрутов вне контроля остается один узел и две дуги. Однако при этом критерии не учитывается комбинаторика сочетания условий на разных участках маршрутов, например, при сочетаниях ветвлений в узлах 3 и 12.
Сложность программы при выделении маршрутов по этому критерию характеризуется числом маршрутов М = 4 и сложностью тестирования = 20. Величина характеризует суммарное количество условий, которое необходимо задать в тестах для полной проверки всех маршрутов, выделенных по первому критерию.
Второй критерий выбора маршрутов f2 для оценки сложности тестирования структуры использует определение цикломатического числа исходного графа проверяемой программы. Этот критерий наиболее полно исследован при анализе корреляции сложности и трудоемкости создания программ. Данный критерий обеспечивает в исходном графе программы однократную проверку каждого линейно независимого ациклического маршрута и каждого линейно независимого цикла, в совокупности образующих базовые маршруты. Каждый линейно независимый маршрут или цикл отличается от всех остальных хотя бы одной вершиной или дугой.
Для примера графа программы, представленного на рис. 2.5, множество проверяемых по этому критерию структур образуется из трех линейно независимых циклов и пяти линейно независимых ациклических структур. Эти ациклические структуры исходного графа образуют циклы в максимально сильно связном графе, если конечный оператор искусственно соединить дугой с входным узлом.
При этом суммарная сложность тестов, учитывающих все условия прохождения маршрутов один раз, становится = 26.
Графы программных модулей может быть удобным представлять в виде матриц или таблиц. Граф программы можно описать матрицей смежности размера n n, где n – число узлов – вершин.
На рис. 2.6 приведен пример матриц смежности для графа программы, представленного на рис. 2.5.
В.В. Липаев. Тестирование компонентов и комплексов программ В этой матрице единица располагается в позиции [i, j], если из вершины i можно перейти к вершине j за один шаг. В противном случае в позиции матрицы размещается 0 (на рис. 2.6 – опускается).
Маршруты в программе можно представить матрицей достижимости, в которой на позиции [i, j] помещается 1, если из узла i можно перейти в узел j за любое число шагов. Описание структуры программ матрицами смежности и достижимости позволяет удобнее вести численный анализ графов и автоматически рассчитывать цикломатическую сложность программных модулей.
Позиции в реальных матрицах оказываются по большей части пустыми (см. рис. 2.6). Это бывает часто, поскольку в графах число узлов, как правило, не превышает значительно число связей. Несмотря на то, что матрицы компактны и их проще рисовать, чем графическую форму модуля, использование такого формата часто затруднительно и приводит к ошибкам при работе с большими матрицами. Если связи обладают весами, они должны в матрице дополняться соответствующими значениями веса.
Анализ матриц достижимости позволяет сравнительно просто выделять циклы и некоторые структурные некорректности (лишние и тупиковые участки графа программы). Номера строк, в которые входят циклы, можно выделить, отмечая диагональные элементы, Лекция 2.1. Тестирование потоков управления программных модулей… равные 1 и одинаковые для нескольких строк элементы, составляющие строку. На рис. 2.6 одинаковыми являются 6 и 8 строки, которые имеют на диагонали 1, в результате чего образуется маршрут с циклом между 6 и 8 вершинами. Аналогично можно выделить еще два маршрута с циклами в 13 строке и в 7, 9, 10, 11, 12 одинаковых строках.
Проектирование тестирования потоков управления Представленные в данной лекции метод стратегии оценки и использования графов потоков управления в программных модулях целесообразно применять при формировании и автоматизации технологии, методики и средств тестирования модулей. Основой могут служить традиционные процессы тестирования: анализ объекта и оценка сложности тестирования, подготовка и исполнения тестов, анализ и корректность результатов тестирования, выявления и ликвидации дефектов и ошибок. Базой значительной части этих процессов могут быть символические модели программ в виде графов, потоков управления и маршрутов исполнения программных модулей, создаваемые на основе преобразования текстов программ на языках программирования. Такая обобщенная визуализация текстов и структуры программных модулей позволяет наглядно представлять логические процессы реализации сложных функций программ, оценивать необходимые ресурсы для тестирования и сопоставлять их с требованиями и эталонами. Проектирование тестов для модулей на базе потоков управления, их выполнения и устранения ошибок целесообразно использовать при разработке технологий и Программ тестирования программных модулей и компонентов для обеспечения их соответствия требованиям высокого качества по следующим этапам (рис. 2.7):
подготовка и построение модели графа узлов и связей модуля на основе текста программы;
выделение, анализ и обеспечение корректности циклов, графа модуля программы;
выделение и тестирование ациклических маршрутов графа модуля программы в соответствие с требованиями к качеству;
фиксирование результатов исполнения каждого теста на выбранном маршруте, устранение дефектов и ошибок и завершение тестирования модуля.
В.В. Липаев. Тестирование компонентов и комплексов программ Проектирование тестов для потоков управления модулей, их выполнение и устранение ошибок должно включать:
- подготовку и построение модели графа узлов и связей программы модуля:
трансляцию текста программы модуля, полученного от программиста в графовую модель узлов и связей между ними;
однозначную нумерацию предложений текста программ модуля и преобразование в имена узлов графа;
преобразование текста программы модуля в виде коротких предложений и предикатов на эквивалентные последовательности узлов и - выделение, анализ и обеспечение корректности циклов графа программы:
выделение в графе модуля циклов, расчет их сложности и развертывание для автономного анализа и тестирования итераций циклической тестирование выделенных циклов по выбранным внутренним маршрутам и итерациям;
- выделение и тестирование ациклических маршрутов графа модуля программы в соответствие с требованиями к качеству;
расчет сложности и проверка первичной корректности структуры ациклического графа модуля для исключения структурных ошибок программистов;
анализ взаимной корреляции предикатов в графе, выделение и исключение нереализуемых путей вследствие противоречий между предикатами;
выделение и упорядоченье маршрутов тестирования по сложности, длительности или вероятности исполнения;
тестирование выбранных маршрутов, при входных величинах, соответствующих проходу по выбранному пути:
согласование с программистами промежуточных численных расчетов и предикатов, которые необходимы для проверки корректности активизирование выбранных маршрутов тестирования по выбранному пути;
- фиксирование результатов исполнения каждого теста на выбранном маршруте, устранение дефектов и ошибок модуля:
определение соответствия тестирования модуля предполагаемому результату, оценка качества, обнаружение и исправление ошибок;
подтверждение и документирование полной корректности выбранных маршрутов потоков управления модулей и завершение тестирования.
Лекция 2.2. Тестирование потоков данных программных модулей…
ТЕСТИРОВАНИЕ ПОТОКОВ ДАННЫХ
ПРОГРАММНЫХ МОДУЛЕЙ
Свойства и тестирование потоков данных В графах потока данных значения объектов связаны с обрабатывающими узлами, в которых эти значения вычисляются. При применении графов потока данных узел может быть использован для представления нескольких различных вычислений и, таким образом, может иметь несколько различных объектов, ассоциированных с исходящими связями. Обычная практика – размещение имен объектов на связях, исходящих из таких узлов. При таком использовании эти имена характеризуются значениями исходящих связей. Поскольку исходящие из одного узла связи являются входящими по отношению к следующему узлу, они называются значениями входящих связей. Узел выбора данных вычисляет специальную функцию значения входящей связи для использования в исходящей связи. Входящие связи узла выбора данных должны быть помечены условием предиката, при котором выбирается данная входящая связь. Его значение выбирает объект данных, соответствующий входящей связи. Обрабатывающий узел с одной или более входящими связями формируется, по крайней мере, с одной исходящей связью. Входящие связи обозначаются именами данных. Исходящая связь обозначает вычисленную функцию этих объектов данных. Запоминающие узлы при последующей обработке должны уточняться, какое именно значение переменной используется: значение, сохраненное на диске, или значение в ОЗУ, предшествующее сохранению. При использовании в сетях с файлами совместного доступа они могут отличаться (и таким образом быть источником ошибок).Тестирование потоков данных можно разделить на два этапа.
Первый этап тестирования состоит в анализе узлов обработки данных, определяющих значения предикатов в операторах выработки логических решений при взаимодействии элементов в модуле программ. Эти решения влияют на изменения маршрутов обработки информации, что сближает в этой части метод тестирования потоков В.В. Липаев. Тестирование компонентов и комплексов программ данных с тестированием структуры модуля. Второй этап тестирование обработки данных на соответствие заданным требованиям.
Оно состоит в проверке вычислений по аналитическим формулам или определение численных значений результатов решения задач в зависимости от числовых или логических значений исходных данных.
Функционирование программного модуля можно рассматривать как обработку потока данных (переменных, предикатов и констант), передаваемых от входа в программу к ее выходу. Входные данные последовательно используются для определения ряда промежуточных результатов вплоть до получения набора выходных данных. Задача тестирования потока данных состоит в установлении корректности их обработки и в выявлении ошибок в тестируемой программе. Эта задача может решаться статически без исполнения программы (анализом ее текста и графа) и динамически – путем исполнения программы на ЭВМ в машинных кодах при различных исходных данных.
Методы тестирования потоков данных более эффективны, чем методы тестирования потоков управления, в том смысле, что они могут обнаруживать больше типов ошибок. Они также более эффективны с точки зрения теории, поскольку можно создать все тесты с помощью тестирования потоков управления и еще некоторые дополнительные тесты для потоков данных. Однако за это приходится расплачиваться.
Чтобы достичь более эффективного тестирования, приходится проделать больше работы. Больше работы, во-первых, при проектировании тестов, а во-вторых, при проверке результатов тестирования. Приведенные ниже методы тестирования, используемые в графах потоков данных, расположены по степени возрастания их эффективности.
Модель потока данных – это способ структурировать мышление, необходимый для получения полезных тестов. Если сделать отдельно модель потока данных и модель потока управления, каждая приведет к различным тестам, и при таком подходе не будет значительного перекрытия созданных тестов. Поэтому полезно помещать модель потока управления внутрь модели потока данных. Повторяющиеся процедуры в модели большей частью определяются потоками данных.
Можно поместить модель потока данных внутрь модели потока управления. Тогда обработка моделируется при помощи графа потока Лекция 2.2. Тестирование потоков данных программных модулей… данных. Выбор способа совмещения моделей потоков зависит от того, какой из них является более сложным и доминирующим.
Данные, участвующие в вычислениях, должны быть определены явно в потоках данных по имени, типу и способу доступа. Это позволяет рассматривать программу в виде мультиграфа, заданного структурой передач управления (потоком управления) и графом преобразования данных, участвующих в вычислениях (поток данных). Пересечение потоков управления и потоков данных осуществляется в узлах ветвления: проверки условий и циклов. Совместный анализ потоков управления и данных позволяет проверять корректность областей определения переменных на маршрутах исполнения программы. Последствия ошибок данных в модуле могут проявляться как малые изменения некоторых переменных в процессе вычислений и как полное искажение или отсутствие на выходе требующихся величин. Тестирование программного модуля целесообразно проводить на упорядоченных наборах данных с учетом степени их влияния на выходные результаты. С этой позиции для последующего анализа целесообразно выделить два вида обработки данных: способный полностью изменять область определения результатов и изменяющий результаты в пределах некоторой ограниченной области определения.
Первому виду обработки соответствуют исходные данные в критических точках (узлах) и на границах областей изменения переменных. При таких критических значениях может изменяться маршрут исполнения программы, вследствие чего возможно наибольшее изменение результатов. Поэтому обычно тестирование обработки данных, прежде всего, направлено на проверку исполнения программ при значениях переменных, влияющих на выбор маршрута и логику функционирования программ (стратегия областей).
Граничные условия – это ситуации, возникающие в непосредственной близости к границам областей изменения обрабатываемых переменных. Число таких критических значений каждой переменной может быть на несколько порядков меньше, чем число значений по всей внутренней части области изменений этой величины. Большинство критических значений (предикатов) может существенно влиять на результаты и подлежит наиболее тщательному тестированию. В этой части тестирование обработки данных по содержанию близко к тестированию структуры (потока управления) программы (см. лекцию 2.1).
В.В. Липаев. Тестирование компонентов и комплексов программ При этом виде тестирования маршруты формируются в процессе анализа и обработки данных на последовательных операторах условий в тексте программы. Таким образом, все множество маршрутов является реализуемым и определяется составом реальных тестовых данных. Сочетания исходных данных в тестах непосредственно влияют на степень охвата тестированием участков программы модуля. Путем сопоставления проверенных маршрутов с маршрутами, выделенными по графу программы при различных критериях можно оценивать полноту тестирования потока управления модуля и приблизительную его корректность.
Второму виду обработки соответствуют данные в ограниченной или неограниченной области определения, которая может делиться на некоторое множество сопрягающихся областей (подобластей). Изменение данных в пределах такой области не влияет на маршрут исполнения программы. Поэтому для проверки функционирования программы из всего множества значений достаточно использовать при тестировании только несколько значений внутри и вблизи границ области. Количество величин, используемых для тестирования при обработке этого вида, может быть на несколько порядков меньше полного числа значений каждой переменной в области. В процессе такого тестирования проверяется точность осуществляемых вычислений, правильность размерности обрабатываемых величин, корректность формирования логических величин и т.д. При этом тестирование должно охватывать всю область изменения каждой обрабатываемой переменной и каждой результирующей величины.
Проектирование и выполнение тестов в модели потока данных остается почти таким же, как в модели потока управления (см.
рис. 2.7). Процессы формирования и тестирования модели потоков данных (без циклов) представлены на рис. 2.8. Тестирование с применением графовых моделей программных модулей способно обеспечивать их высокое и управляемое качество. Оно состоит из двух технологических этапов: построения и анализа графовой модели для подготовки тестирования и этапа планирования, реализации и исполнения тестов для выявления дефектов и ошибок в программе. При планировании тестирования на основе объединенной графовой модели потоков управления и данных подготавливаются исходные данные требований и эталонов и обобщенный граф модели модуля. Эти данЛекция 2.2. Тестирование потоков данных программных модулей… ные используются для определения предикатов и переменных правильных маршрутов исполнения программы и описаний тестов.
Формирование и тестирование потоков данных модуля построение и анализ графовой модели для подготовки тестирования:
идентификацию входных переменных и констант, присвоение каждой входной переменной имени и создание для преобразование спецификации и текста программы модуля, чтобы каждой вычисляемой функции соответствовало перечисление функций – подграфов и создание структуры узлов модуля, пока не охвачены все потоками данных;
формирование списка, в котором находятся промежуточные подграфы, зависящие от большого количества вычислений;
проверка промежуточных функций, можно ли упростить модель, удаляя промежуточные узлы между подграфами;
проверка возможности упростить модель, добавляя промежуточные узлы и подграфы для сложных вычислений;
регистрация модели потока данных модуля – функций, связей и подграфов, которые отражают их обработку;
проверка полноты и корректности модели потока данных;
- планирования, реализации и исполнения тестов для выявления дефектов и ошибок в программе:
выбор маршрутов тестирования с использованием порожденных подграфов;
предсказание и регистрация ожидаемых результатов – эталонов тестирования выбранных маршрутов и подграфов;
определение критериев соответствия эталону для каждого выполнение тестов потоков данных на выбранных маршрутах и подграфах;
сравнение результатов тестирования маршрутов и подграфов с эталонами, регистрация дефектов и ошибок;
исправление дефектов и ошибок и регрессионное тестирование маршрутов и подграфов.
В.В. Липаев. Тестирование компонентов и комплексов программ Маршруты формируются в соответствии с заданной стратегией и критерием выделения и упорядочивания маршрутов. Сформированные тесты используются для контроля исполнения программы компонента и выявления ошибок.
Подготовка тестов потоков данных модуля начинается с проверки корректности его спецификации, идентификации входных переменных и констант, присвоение каждой входной переменной имени и создание для нее входного узла. Текст программы модуля преобразуется так, чтобы каждой вычисляемой функции соответствовало одно предложение. Создается структура компонента, начиная с элементов, которые зависят от входных переменных и от результатов предыдущих функций, пока не охвачены все. Производится проверка промежуточных функций, является ли их упорядочение необходимым или просто удобным, можно ли упростить модель, удаляя промежуточные узлы или, добавляя промежуточные узлы и подграфы для сложных вычислений. Следует зарегистрировать модель потока данных – поименованный набор узлов – функций, их связей и подграфов, которые отражают их обработку.
Планирование и реализация тестирования модуля с использованием графов потоковых моделей программ начинается с формирования задания, эталонов и ограничений для планирования тестирования программного модуля (см. рис. 2.8). На основе подготовленного графа программного компонента должно производиться выделение циклических подграфов для автономного тестирования, использование предикатов и маршрутов циклов для формирования набора тестов и выполнение их тестирования. После этого целесообразно осуществлять выбор маршрутов тестирования по узлам и порожденным ими сложным вычислительным подграфам и активизирование тестирования порожденных подграфов. В результате возможно преобразование объединенной графовой модели к ациклическому виду. В этой модели производится выделение маршрутов по выбранному критерию и упорядочение выделенных маршрутов графа по выбранной стратегии ациклического графа исполнения программы. Далее целесообразно провести анализ и исключение нереализуемых маршрутов графа по противоречивым условиям в предикатах или на граничных значениях переменных. Оставшийся список предикатов и выделенных маршрутов используется для предсказания и записи ожидаемых итогов тестирования маршрутов, формирования набора тестов Лекция 2.2. Тестирование потоков данных программных модулей… и реализации тестирования по выбранным маршрутам и подграфам.
Это позволяет оценить полное число тестов, использованных для тестирования выделенных маршрутов с учетом значений эталонов и ограниченных ресурсов, а также степень покрытия модуля тестами, проконтролировать результаты тестирования, выделенные дефекты и ошибки. При этом должна быть проведена оценка качества программного модуля и допустимости его применения в проектируемом комплексе, подтверждена корректность значений результатов в промежуточных узлах, циклах и подграфах. Все итоги тестирования должны быть документированы. Ниже представлены некоторые методы тестирования, используемые в графах потоков данных при выборе маршрутов в порядке возрастания их эффективности.
Покрытие ввода/вывода. Для каждого выходного узла используется набор входных значений, которые приводят к определенному значению вывода. В этом методе есть слабое место: покрытие входных и выходных узлов и, возможно, некоторых промежуточных узлов, но если среди них имеется отдельный предикат выбора, можно быть уверенным, что используется только одно значение этого предиката, другие не будут протестированы. Эта проверка слишком слаба, чтобы быть полезной. Она гарантирует только то, что программный модуль работает для одного набора входных данных.
Ввод/вывод + все предикаты. Усиливается покрытие ввода/вывода так, чтобы все предикаты (включая предикаты потока управления для циклов и другого необходимого упорядочения) были проверены для обоих значений истинности и аналогично для предикатов в операторах. Это лучше, но если есть промежуточные вычисления, результаты которых не используются, они не обнаруживаются. Вычисление чего-либо без последующего использования полученного результата – это, скорее всего, ошибка, которая чаще всего является лишь неоправданной тратой ресурсов, но иногда может быть опасна. Следовательно, промежуточное вычисление, выход которого не используется, по всей видимости, является ошибкой, и ее следует обнаружить. Если просто проверены все узлы с предикатами (как потока управления, так и выбора данных), это больше, чем тестирование ветвей потока управления (из-за проблемы составных предикатов), но не получены все преимущества, которые дает тестирование потоков данных.
Частичное покрытие узлов. Предыдущие методы обеспечивали покрытие некоторых узлов и некоторых связей, но при этом не гарантировали, что будет обеспечено покрытие всех узлов и/или всех свяВ.В. Липаев. Тестирование компонентов и комплексов программ зей. Это называется стратегией всех определений, поскольку каждый вычислительный узел в модели потока данных соответствует определению некоторой переменной. Однако это не обеспечивает полное покрытие связей. Таким образом, эту стратегию нельзя прямо сравнивать со стратегией ввод/вывод + предикат, описанной ранее. Это означает, что каждая функция была выполнена хотя бы один раз и дала правильное значение для этого случая. Проведена проверка промежуточных результатов, поскольку тестирование каждого вычислительного узла и подграфа подразумевает проверку вычисления, сделанного в этом узле.
Все узлы покрывают узлы, а не только вычислительные – обеспечено покрытие всех узлов выбора данных и узлов потока управления.
Но это недостаточно сильно, поскольку не дает гарантии, что проверены все варианты для предикатов выбора и потока управления.
Покрытие связей – охват всех связей в графе потока данных. Она соответствует стратегии всех использований вычислений. Всякий раз, когда вычисление выполнено, будет проверяться каждое использование результата этого вычисления подграфа в последующей обработке.
Это подразумевает проверку всех промежуточных вычислений, а не только конечных выводов. Но это не означает тестирования каждого возможного пути в программе. Это даже не тестирование всех возможных путей между точкой определения и местом его последующего использования.
Тестирование графов модулей программ с учетом значений переменных и констант Анализ и учет при тестировании областей определения значений переменных и констант. При анализе обработки данных в пределах внутренних областей их определения методы тестирования целесообразно применять упорядоченно в следующей последовательности:
тестирование корректности записи и считывания переменных при вычислениях и полноты состава выходных данных на всех маршрутах исполнения программы;
тестирование точности результатов вычислений и корректности обработки каждой переменной или константы;
Лекция 2.2. Тестирование потоков данных программных модулей… тестирование на полное соответствие состава и значений выходных данных требованиям программной спецификации.
В приведенной последовательности частные методы тестирования обработки данных позволяют, прежде всего, выявлять первичные ошибки, которые способны искажать результаты в наибольшей степени. При ограниченных ресурсах и такой последовательности тестирования в программе будут оставаться ошибки, наименее влияющие на корректность выходных данных. Полезно акцентировать внимание на выявление ошибок обработки данных, которые влияют на логику исполнения программы, запись и считывание переменных, полноту состава результатов, точность расчета выходных данных и полное соответствие выходных данных требованиям спецификации модуля или компонента. На основе таких проверок может оцениваться степень охвата тестированием всех условий, определенных в спецификации, и дополнительное тестирование следует проводить только при отдельных недостаточно проверенных входных или результирующих данных – рис. 2.9.
Тестирование графов модулей программ с учетом значений переменных и констант должно включать:
- анализ и учет при тестировании областей определения значений переменных и констант;
- учет граничных значений переменных и констант при тестировании потоков данных;
- тестирование корректности определения и использования данных на маршрутах исполнения программ;
- тестирование корректности и точности вычислений каждой - определение и регистрация не реализуемых маршрутов потоков данных программных модулей.
Маршруты последовательности обработки данных могут зависеть от любых типов величин. При выборе направления ветвления в узлах графа программы участвуют переменные и константы, отражающие вещественные, целые, булевские, символьные, векторные и другие величины. Области определения таких величин зависят от их типов и содержания и могут представлять как отдельные точки и несвязанные области, так и неограниченную непрерывную последоваВ.В. Липаев. Тестирование компонентов и комплексов программ тельность значений. Одной из задач тестирования является проверка сопоставимости сравниваемых типов величин и идентичности условий их кодирования (разрядности, масштабов и т.д.). Критические значения – предикаты, влияющие на маршруты, во многих случаях не являются фиксированными, а формируются при сопоставлении нескольких переменных или при их преобразованиях. При этом предикаты образуются во всей области изменения каждой из переменных, например, когда они оказываются равными или отличаются на некоторую постоянную величину.
Предикаты, определяющие выбор маршрутов исполнения программных модулей систем управления, формируются в результате вычислений в узлах обработки на линейных участках программы.
Эти участки в среднем невелики и содержат около 10 операторов программы. Вычисления в большинстве случаев представляют собой простейшие линейные преобразования входных или промежуточных данных. По оценкам 95 – 97% арифметических операторов включают только сложение и вычитание, а 98% всех выражений между последовательными предикатами содержат не более двух операторов. Кроме того, предикаты обычно очень простые – в большинстве случаев с одной входной переменной и практически отсутствуют предикаты, использующие более двух входных переменных. Нелинейные предикаты встречаются очень редко (0,1 – 0,3%). Приведенные данные позволяют ограничить анализ линейными предикатами, характерными для широкого класса программ управления.
Учет граничных значений переменных и констант при тестировании потоков данных. Каждая ограниченная область исходных данных соответствует определенному маршруту в программе.
Граница области определяется интерпретациями предикатов по маршруту и состоит из набора участков границы, каждый из которых определяется единственным простым предикатом, формирующим дугу маршрута в графе программы. Каждый участок границы области может быть открытым или закрытым в зависимости от оператора условий в предикате (рис. 2.10). Закрытый участок границы принадлежит ограничиваемой области и формируется предикатами с операторами, или =. Открытый участок границы не входит в состав области и формируется операторами <, > и. Общее число предикатов в маршруте – это верхний предел числа граничных участков области входных переменных данного маршрута, так как некотоЛекция 2.2. Тестирование потоков данных программных модулей… рые предикаты маршрута могут в действительности не создавать граничных участков. Такие случаи возникают, когда предикат требуется для нескольких путей и в некоторых из них повторно анализируется на маршруте.
Предикаты можно разделить на три типа: равенство (=), отношение больше – меньше ( <, >,, ) и неравенство ( ). Использование предикатов каждого типа дает существенно различный эффект на границе области. Предикаты каждого маршрута определяют некоторую гиперплоскость в пространстве. Ограничения типа неравенства эквивалентно составному предикату (AB), такой предикат приводит к разделению исходной области на две части. Предикаты типа равенства и больше – меньше приводят к формированию области в виде единственного многоугольника. Многоугольник является выпуклым, если для любых двух точек области участок границы, формирующий маршрут, входит в состав этой области. Если в состав предикатов ввести неравенства, то пространство входных данных будет объединением множества выпуклых многоугольников.
Таким образом, программа по отношению к потоку данных, прежде всего, выполняет функцию разделения пространства исходных данных на области, каждая из которых соответствует одному исполняемому маршруту. Ошибки в программе могут быть обусловлены модификацией границы области определенного маршрута, приводящей к расширению или сужению пространства исходных данных соответствующего маршрута. Кроме того, деформация границ областей может приводить к ошибкам уничтожения некоторых областей и потере соответствующих им маршрутов. Причинами таких ошибок могут быть искажения операторов анализа условий или искажения в процессе вычисления значений предикатов при правильном содержании оператора условия. В последнем случае обычно сдвигается граница области, однако она сохраняет общую структуру.
Искажения операторов анализа условий может приводить как к деформации границы области, так и к появлению новых границ или их уничтожению, вследствие чего области могут разделяться или сливаться.
Один из достаточно часто встречающихся типов ошибок обусловлен искажениями условий формирования границ областей. Выбор тестовых данных вблизи границ областей обеспечивает наибольшую чувствительность к этим ошибкам. Тестовые исходные данные в зависимости от их положения относительно конкретной границы обВ.В. Липаев. Тестирование компонентов и комплексов программ ласти можно разделить на два вида. Первый вид данных (принадлежащая точка) размещается на границе области. При тестировании граничные точки входят в состав проверяемой области (условия,, = ). Второй вид (непринадлежащая точка) отстоит от границы на сколь угодно малую величину и находится на открытой стороне данной области (условия, ). При тестировании такой области принадлежащие (граничные) точки относятся к смежной области, а в проверяемую область данная граница не входит.
Для проверки границ областей разработана стратегия выбора тестовых значений, минимизирующая объем проверок. Для закрытой области на каждой границе целесообразно формировать три тестовых значения. Первые два теста (A и B) (см. рис. 2.10) размещаются на границе данной области вблизи стыка данной границы с соседними.
Третья точка (C) размещается на малом расстоянии от данной границы и удовлетворяет всем неравенствам области, кроме проверяемого на данной границе. При таких тестовых данных должны получаться выходные результаты, искажения которых обусловлены невыполнением условия на анализируемой границе.
При любом сдвиге границы областей на величину, большую, обнаруживается ошибка. Действительно, если анализируемая граница сдвинута во внешнюю область по сравнению с заданной на величину, большую, то в точке C выполнится условие, анализируемое на границе, что является указанием наличия ошибки. При сдвиге границы внутрь анализируемой подобласти неправильно выполняются тесты в точках A и B или в одной из них. При таком расположении контрольных точек обнаруживаются не только ошибки вычислений, используемых в предикатах, но и ошибки операторов предикатов и маршрутов. Даже в случае ошибочной замены неравенства на < ошибка обнаруживается в результате неправильных данных в точках A и C.
Для проверки области изменения данных, образующих маршрут, необходимо тестировать граничные значения каждого предиката. В зависимости от числа ветвлений в каждом маршруте может иметься nв таких границ. Для каждой границы, как показано выше, необходимо иметь три тестовых значения. Однако число тестовых значений можно несколько сократить, если крайние из них выбирать на пересечениях соседних границ. В результате число тестов для каждого маршрута лежит в пределах 2n в 3n в.
Лекция 2.2. Тестирование потоков данных программных модулей… Дальнейшее сокращение числа тестовых значений возможно, если учитывать корреляцию условий на различных маршрутах, имеющих общие границы областей. В ряде случаев проверка программы в точках A и C (см. рис. 2.10) может проводиться только на одном маршруте, соответствующем нижней части области изменения данных. На маршруте, использующем верхнюю часть области, достаточно тестировать только при тестовых значениях, соответствующих точке B.
Для полной проверки предиката строгого равенства необходимы два теста на границе условия равенства значений и два теста, имеющие малые отклонения от этой границы. Таким образом, по сравнению с проверкой неравенств в данном случае прибавляется еще один тест. При этом гарантируется обнаружение ошибок как в операторе предиката, так и в расчете данных при формировании границы анализируемого условия. Приведенный подход полностью может быть отнесен к анализу предикатов типа строгого неравенства.
Проверка совокупности маршрутов, содержащих строгие неравенства и равенства, может быть сокращена, если учитывать при последовательном тестировании уже проверенные области.
При использовании стратегии областей по признаку их выпуклости могут автоматически выделяться неверные предикаты. Если одна из граней многогранника приводит к нарушению его выпуклости, то область считается аномальной и может быть локализован преВ.В. Липаев. Тестирование компонентов и комплексов программ дикат, содержащий ошибку. Последовательный попарный анализ предикатов на их совместимость и непротиворечивость позволяет отсеивать некоторые нереализуемые маршруты. Тем самым в ряде случаев значительно сокращается необходимый объем тестирования модуля.
Приведенный метод упорядоченного регулярного тестирования на основе определения областей изменения данных является весьма эффективным. Сложность тестов линейно растет с увеличением размерности пространства исходных данных (числа переменных) и с ростом числа предикатов на маршрутах. Для многих типовых модулей сложность тестов потока данных оказывается допустимой для полной проверки модуля. Ограничения метода проверки областей могут проявляться при сложных организациях циклов, когда резко возрастает число маршрутов и анализируемых условий. Значительные трудности возникают при нелинейных предикатах. Даже нахождение точек пересечения нелинейной границы с множеством линейных границ может потребовать сложных вычислений. При использовании в программе операторов «или» необходимо установить характер перекрытия областей, соответствующих анализируемому оператору, что требует дополнительных расчетов. Тем не менее, метод анализа областей изменения данных может существенно упорядочить тестирование программ и сократить число ошибок.