КАТЕГОРИИ: Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748) |
Тестирование обработки потоков данных программными компонентами
Эффективность тестирования определяется полнотой проверки программного модуля или вероятностью наличия не выявленных ошибок в зависимости от затрат ресурсов: на создание тестов, исполнение программ и анализ результатов тестирования. Затраты в значительной степени зависят от суммарной сложности формирования тестов, проверяющих маршруты исполнения программы. На каждой дуге графа программы между условными переходами производятся вычисления и преобразования переменных, объем которых может изменяться в широких пределах. Для упрощения анализа и оценивания тестирования структуры программ предположим, что длительность и сложность вычислений на дугах графов программ одинаковы и относительно невелики. Некоторые вершины графа программы могут образовываться в результате схождения дуг без последующего ветвления. Такие вершины не влияют на число маршрутов, и их можно обобщать с ближайшей последующей вершиной, в которой происходит ветвление. При этих предположениях сложность теста, проверяющего каждый i-й маршрут, в первом приближении пропорциональна числу дуг графа программы, входящих в этот маршрут, или числу E i условий, которые необходимо задать в тесте. Экспериментально подтверждена адекватность использования структурной сложности программ для оценки трудоемкости тестирования, а также вероятности наличия не выявленных ошибок и затрат на разработку программных модулей в целом. Сложность тестирования ПМ можно оценивать по числу маршрутов M X , необходимых для их проверки, или более полно по суммарному числу условий Е X, которое необходимо задать в тестах для прохождения всех маршрутов программы, выделенных по Х-му критерию: (13.1) где Е i - число условий-предикатов, определяющих i -й маршрут. Маршруты исполнения программного модуля можно разделить на два вида: - маршруты исполнения преимущественно вычислительной части программы и преобразования непрерывных переменных; - маршруты принятия логических решений и преобразования логических переменных. Маршруты первого вида обычно логически проще и короче, чем второго, и предназначены для преобразования величин, являющихся квантованными результатами измерения некоторых непрерывных физических характеристик (непрерывные переменные). Значения таких переменных связаны условиями гладкости, т.е. условиями малых изменений производных этих переменных по времени или по другим параметрам. При оценке сложности вычислительных маршрутов программ необходим учет числа операндов, участвующих в вычислениях. Кроме того, исходные и результирующие данные при тестировании должны принимать несколько значений. Во всем диапазоне исходных переменных следует выбирать несколько характерных точек (предельные значения и несколько промежуточных), при которых проверяется программа. В особых точках значений и сочетаний переменных и в точках разрыва функции необходимо планировать дополнительные проверки. Таким образом, сложность проверки программного модуля будет определяться числом маршрутов M Х исполнения программы и числом обрабатываемых операндов l i на каждом i -м маршруте, умноженном на число значений s i j для каждой исходной j -й величины на этом маршруте: (13.2) Расчет показателя сложности тестирования программного модуля по такойсхеме имеет значительную неопределенность из-за произвола в выборе числа значений s i j (в основном, особых точек) при варьировании исходных данных в тесте. В то же время доля вычислительной части во многих сложных ПС относительно невелика. Второй вид маршрутов является результатом функционирования схем принятия решений и преобразования логических переменных. Для логических переменных отсутствует сильная корреляционная связь между соседними значениями, и каждое изменение переменной может определять разные области результирующих значений. Такое преобразование переменных обеспечивается алгоритмами со сложной логической структурой, содержащей ряд проверок логических условий, циклов для поиска и селекции переменных, а также логические преобразования переменных. В результате в программе образуется множество маршрутов обработки исходных данных, которые определяют сложность структуры программы. Структурная сложность программного модуля может быть рассчитана по числу маршрутов М Х в программе и сложности каждого i -го маршрута Е i . Эти показатели в совокупности определяют минимальную сложность Е Х тестов для проверки программного модуля (13.1), а следовательно, трудоемкость его разработки и тестирования, и вероятность пропуска логической ошибки в программе. Программные модули являются наиболее массовыми компонентами в ПС и требуют для тестирования суммарно наибольших затрат ресурсов. Затраты на тестирование каждого модуля прямо пропорциональны сложности, которая зависит от его структуры и объема вычислений l i . При тестировании программного модуля необходимо задать и проанализировать число значений параметров: (13.3) Суммарные затраты ресурсов на тестирование модуля пропорциональны значению егосложности В Х и, с учетом удельных затрат на создание каждого теста - с, определяются выражением: (13.4) Значение множителя c зависит от степени автоматизации процесса тестирования и генерации тестов. В высокоавтоматизированных системах сокращаются затраты ручного труда на подготовку и анализ тестовых данных, однако увеличиваются затраты на машинное время, необходимое для генерации тестов и для автоматической обработки результатов тестирования. В зависимости от этих факторов значения множителя c могут различаться в несколько раз, и их следует экспериментально определять для каждой системы автоматизации тестирования. Сложность тестирования программ, содержащих циклы. Наличие циклов в программе способно резко увеличивать сложность их тестирования. Полное, исчерпывающее тестирование должно охватывать проверку каждого маршрута в цикле при всех возможных итерациях цикла и при всех сочетаниях циклов с маршрутами ациклической части программы. Предположим для простоты, что число маршрутов в нижней ациклической части программы равно М 3 =1. Тогда полное множество маршрутов M состоит из полной совокупности всех маршрутов M1 в верхней ациклической части программы и группы маршрутов M 2, в которой к каждому маршруту из M 1 присоединено 1..2..3... итерации (витка) цикла. При этом на каждой итерации выполняется, по крайней мере, один из внутренних маршрутов тела цикла. Например, для графа, имеющего один цикл, требующего исполнения пяти итераций (витков) с тремя внутренними маршрутами, а также содержащего M 1 = 10 ациклических маршрутов, проходящих через цикл, суммарное число маршрутов для исчерпывающего тестирования равно M = (3 x 5) x 10 = 150. При возрастании любого из сомножителей (числа независимых ациклических маршрутов, проходящих через цикл, числа внутренних маршрутов тела цикла или числа его итераций) пропорционально растет их произведение, а, следовательно, и сложность тестирования. Поэтому исчерпывающее тестирование реальных сложных программ с циклами может быть практически невозможно. На сложность тестирования цикла оказывает влияние его структура и два параметра: число маршрутов в теле цикла и число итераций цикла. В динамике реального исполнения простейшего цикла между его итерациями могут существовать зависимости, по крайней мере, трех видов: - на разных итерациях цикла исполняются независимо все возможные маршруты тела цикла; - на всех итерациях цикла исполняется один и тот же маршрут тела цикла или некоторая определенная их последовательность; - на разных итерациях цикла в силу наличия семантических связей исполняется подмножество реализуемых маршрутов тела цикла, зависящее от данных или от номера итерации. При зависимости первого вида, которая встречается наиболее редко, возникает необходимость в полном переборе всех внутренних маршрутов тела цикла в сочетании с каждым числом итераций. В этом случае сложность тестирования цикла определяется сразу обоими параметрами: числом маршрутов тела цикла и числом итераций и приближается к сложности исчерпывающего тестирования. При зависимости второго вида число маршрутов тела цикла практически не влияет на сложность цикла. Определяющим становится количество итераций, необходимых для тестирования вычислений в теле цикла (например, с учетом требуемой точности). При третьей, наиболее распространенной зависимости, определяющим при оценке сложности тестирования является не число итераций цикла, а число маршрутов тела цикла. Простейшие оценки сложности циклических структур целесообразно проводить в предположении, что порядок реализации маршрутов тела цикла не зависит от номера итерации. В этом случае при оценке сложности циклических структур конструктивным является подход с позиции минимально необходимого числа проверок итераций циклов. Для оценки сложности структурного тестирования ациклических логических программ с простейшими циклами целесообразно уточнить критерии проверки. По первому критерию ациклическая часть программы покрывается минимальным числом маршрутов, в которые входят маршруты, проходящие через цикл, размыкающие его и образующие минимальное покрытие тела цикла. Кроме того, к покрытию добавляется маршрут, содержащий замыкающую дугу цикла. По второму критерию ациклическая часть программы проверяется количеством тестов, равным сложности ациклической части программы. При этом к каждому такому маршруту присоединяются все примыкающие к нему циклы. Проверка каждого цикла осуществляется одним маршрутом, содержащим столько итераций, какова сложность тела цикла, а тело цикла покрывается линейно независимыми маршрутами. При таких оценках определяющими факторами являются полнота проверки тела цикла, условий его замыкания и размыкания. При этих критериях сложность цикла наиболее просто оценить, представив его эквивалентным ациклическим подграфом. Например, при втором критерии эквивалентным циклу с одной точкой входа и одной точкой выхода будет линейный подграф, содержащий последовательно соединенные все линейно независимые маршруты тела цикла, связывающие его точку входа с точкой выхода. Такой эквивалентный ациклический подграф добавляется к каждому маршруту в покрытии ациклической части графа по этому критерию. При применении вложенных циклов со сложной структурой и с большим числом ветвлений в теле цикла сложность тестирования резко возрастает и повышается вероятность сохранения в программе необнаруженных ошибок. Однако циклы с простейшей структурой приводят к относительно небольшому увеличению суммарной сложности тестов. Поэтому в процессе проектирования программ необходимо в максимальной степени упрощать циклические компоненты в структуре, которые во многих случаях определяют достигаемую корректность программных модулей при их тестировании. Выражение (13.3) целесообразно использовать для выявления сложных модулей, требующих наибольших затрат на тестирование, и для рационального распределения ограниченных ресурсов тестирования модулей при создании крупномасштабных комплексов программ. Некоторые модули могут оказаться недостаточно протестированными из-за их высокой сложности и необходимости больших затрат, которые всегда ограничены. Ограниченность ресурсов на тестирование программных модулей приводит к целесообразности выравнивания их структурной сложности и выделения затрат на проверку в соответствии со сложностью каждого модуля. Особенно сложные модули следует делить на более мелкие и простые, и так перестраивать их структуру, чтобы сокращалось суммарное число маршрутов в каждом отдельном модуле и их длина. Сложность тестирования программных компонентов (функциональных групп программ) определяется суммарной сложностью модулей и межмодульных связей по управлению и по информации. Каждый модуль должен тестироваться автономно до включения в группу программ и частично в составе группы. Затраты на тестирование модулей в составе группы программ должны учитывать относительные суммарные затраты на тестирование всех входящих модулей с коэффициентом d k <1, зависящим от степени предшествующей проверки модуля. Если модули автономно не тестировались (например, при нисходящем тестировании), то d k =1 и затраты на тестирование каждого модуля войдут в затраты при тестировании группы программ в полном объеме. При тщательном автономном тестировании модулей можно полагать d k = 0,1-0,01, т.е. в составе ПС затраты на тестирование каждого из модулей составляют несколько процентов. 13.5. Примеры оценок сложности тестирования программ Приведенные выше выражения можно использовать для априорной оценки числа маршрутов и сложности тестирования (необходимого числа тестов для охвата всех выделенных маршрутов) программных модулей. Для планирования тестирования необходимо выявить зависимости этих характеристик от числа операторов в программе, ее структуры и критериев выделения маршрутов. Эту задачу можно решать экспериментально, путем подсчета соответствующих характеристик в реальных программных модулях, используемых в различных классах ПС. Для выявления общих зависимостей сложности тестирования программ целесообразно выделить типовые программные структуры, а также такие, которые позволяют получить предельные (сверху и снизу) значения этих характеристик. На рис. 13.7 представлен пример исходного графа модуля программы, содержащего 14 вершин, 20 дуг и 3 цикла. Такая программа сравнительно невысокой сложности содержит около 30-50 операторов на языке высокого уровня и может рассматриваться как достаточно типичная. Для полной проверки модуля по первому критерию достаточно четырех маршрутов. По этому критерию гарантируется проверка всех передач управления между операторами программы и каждого оператора не менее одного раза. Самый длинный по числу вершин маршрут не охватывает только 3 вершины из 14 и только 6 дуг из 20. После проверки еще двух маршрутов вне контроля остается одна вершина и две дуги. Однако при этом критерии не учитывается комбинаторика сочетания условий на разных участках маршрутов, например, при сочетаниях направлений ветвлений в вершинах 3 и 12. Сложность программы при выделении маршрутов по этому критерию характеризуется числом маршрутов равным четырем и сложностью тестирования равной 20. Эта величина характеризует суммарное число условий, которое необходимо задать в тестах для полной проверки всех маршрутов, выделенных по первому критерию. Условия в вершинах каждого маршрута могут использоваться для автоматизированного формирования предикатов в соответствующих тестах. Второй критерий выбора маршрутов при оценке сложности тестирования обеспечивает в исходном графе программы однократную проверку каждого линейно независимого ациклического маршрута и каждого линейно независимого цикла в совокупности образующих базовые маршруты. Каждый линейно независимый маршрут или цикл отличается от всех остальных хотя бы одной вершиной или дугой. Этот критерий наиболее полно исследован при анализе корреляции сложности и трудоемкости создания программ. Множество проверяемых по этому критерию структур образуется из трех линейно независимых циклов и пяти линейно независимых ациклических структур. При этом суммарная сложность тестов, учитывающих все условия прохождения маршрутов один раз, становится равной 25. Наиболее глубокий третий критерий проверки и определения сложности тестирования структуры программы включает требования однократной проверки не только линейно независимых, но и всех линейно зависимых циклов и ациклических маршрутов. Он заключается в анализе хотя бы один раз каждого из реальных ациклических маршрутов исходного графа программы и каждого цикла, достижимого из всех этих маршрутов. Для примера графа программы, представленного на рис. 13.7, по данному критерию необходимо исполнить 6 ациклических и 5 маршрутов, из которых достижимы элементарные циклы. Для реализации выделенных маршрутов в 11 тестах необходимо в совокупности задать 66 условий. При этом особенностью четырех последних маршрутов с циклами, также как соответствующих им ациклических маршрутов, является полный перебор сочетаний ветвлений в 3 и 12 вершинах. В реальных программах некоторые маршруты могут оказаться нереализуемыми из-за несовместимости условий, которые последовательно анализируется в разных вершинах (например, вершины 3 и 12 на рис. 13.7). С другой стороны, для каждого реализуемого маршрута может быть необходимой проверка при нескольких прохождениях циклов и нескольких значениях каждой обрабатываемой переменной. Особенно важно проверять циклы с условным выходом на одном-двух промежуточных, а также при максимальном и минимальном числе витков исполнения циклов. В результате показатель сложности, число необходимых тестов и длительности проверки соответственно возрастают. Для выявления основных закономерностей и оценки предельных характеристик структурной сложности тестирования ПМ проведен анализ характеристик качества тестирования абстрактных ациклических программных модулей и представительной выборки реальных модулей сложных ПС. Исследование реальных ПМ показало, что более половины из них не содержат циклов, что позволило сосредоточить на них внимание. Предполагалось, что после тестирования по любому маршруту каждой дуги графа программы вероятность наличия ошибки в этой дуге равна нулю. Ветвления в программах объектных ЭВМ происходят через 5 – 10 операторов текста программ, поэтому число маршрутов исполнения ациклических ПМ пропорционально их объему, выраженному числом строк текста программ. Анализ проведен для двух типов ациклических графов при выделении маршрутов по критерию охвата каждой дуги графа программы хотя бы один раз X1 и по критерию выделения всех маршрутов, различающихся хотя бы одной дугой Х2. В числе выбранных содержатся структуры, охватывающие наиболее типовые варианты компонентов графов программ. Структуры различались шириной графов, вследствие чего отличались число маршрутов и сложность полного тестирования таких структур. Сложность тестирования ПМ оценивалась по числу маршрутов исполнения программы, отражающих число тестов, необходимых для полной проверки корректности структуры модуля. Кроме того, в качестве показателя структурной сложности тестирования анализировалось суммарное число условий, которое необходимо задать в тестах (сложность тестирования) для проверки модуля. Граф Г1 представлял собой симметричное упорядоченное бинарное дерево с максимальным использованием различных ветвлений и максимальной шириной. В графе Г2 наоборот, ширина минимальная и всего два полностью различающихся маршрута. При выделении маршрутов по первому критерию в графе Г2 только два маршрута и не зависит от числа вершин ветвления. В графе Г1 при выделении маршрутов по первому критерию их число линейно возрастает при увеличении числа вершин. При выделении маршрутов по второму критерию их число пропорционально полному числу вершин дляэтих типов графов. Структурная сложность тестирования графов ПМ изменяется в более широком диапазоне, чем число маршрутов, что определило выбор логарифмического масштаба пооси ординат на рис. 13.8. Наименьшей структурной сложностью характеризуется граф Г2 при выделении маршрутов по первому критерию. Длятаких графов структурная сложность возрастает практически линейно в зависимости от числа вершин. При выделении маршрутов по второму критерию тот же граф характеризуется наибольшей структурной сложностью. При 30 и более вершинах структурная сложность этого графа почти на порядок выше, чем графа Г1 притом же числе вершин. Относительная разница сложности тестирования этих графов при критерии Х2 приблизительно сохраняется приизменении числа вершин от 16 до 100. Такое распределениезначений структурной сложности оттипов графов обусловлено различием их ширины. Таккак число маршрутов при критерии Х2 в зависимости от числа вершин вовсехграфахизменяется практически одинаково, то определяющим различия структурнойсложности являетсячисло условий анализируемых в каждом маршруте. Во всех маршрутах графа Г2 участвуют все его вершины, что определило его наибольшую структурную сложность. На рис 13.8 точками (с указанием числа совпадающих значений) отмечены значения структурной сложности тестирования около 70 реальных ациклических ПМ в двух системах. Характеристики абстрактных графов Г1 и Г2 действительно охватывают диапазон изменения показателей сложности тестов для реальных программ, которые по каждому критерию группируются приблизительно посередине. Максимальная сложность тестов по второму критерию для произвольных ациклических программ близка к числу вершин в квадрате. По тому же критерию минимальная сложность тестов для широких структурированных графов типа дерево на порядок меньше максимальной сложности. Для усредненных оценок сложности полных тестов произвольных ациклических программ хорошее приближение для инженерных оценок при n в > 10 дает выражение n в 2 /3 (штриховая линия на рис. 13.8). Характерно, что увеличение числа вершин в 4 раза (от 32 до 128) для рассмотренных графов приводит к возрастанию структурной сложности более чем в 10 раз. Если же программу, имеющую 128 вершин, разделить на 4 модуля, то их суммарная сложность практически равна только учетверенной сложности модулей, содержащих по 32 вершины. Исследованные реальные ПМ 80% случаев содержат не более 10 вершин и имеют структурную сложность тестирования < 50. Показано, что при разработке ПМ целесообразно учитывать рациональное ограничение размеров модулей на уровне трехсот строк текста, что соответствует приблизительно тридцати альтернативам в ациклических программах. При этом для полного покрытия таких ПМ тестами необходимо задавать до 1000 условий, что обычно достаточно трудно или невозможно реализовать практически. В среднем полное тестирование программ с 30-ю вершинами ветвления производится тестами с суммарной сложностью около 300 – 500. Суммарная сложность тестов, необходимых для полного тестирования программ, имеющих различные структуры, может отличаться в несколько раз. Поэтому при разработке ПМ рекомендован рациональный размер программ модулей в пределах 100 – 200 строк текста, для полного тестирования которых достаточно использовать 10 – 20 тестов с суммарным числом условий ветвления до 100. При превышении рекомендуемых размеров ПМ их трудно протестировать полностью и целесообразно делить на более мелкие компоненты, доступные для практически полного покрытия тестами. Для получения практических оценок достигаемой корректности программы при покрытии тестами ее структуры, необходимо оценить диапазон реальной вероятности ошибки допускаемой квалифицированным программистом первично в каждой дуге графа программы. Экспериментально установлено, что для слабо структурированных программ число ошибок, выявляемых в процессе тестирования программных модулей, составляет около одного процента числа строк текста этих модулей. Для программ обработки информации и управления число условных переходов составляет около 10% числа строк в программе, т.е. ветвление в программе происходит в среднем после исполнения 10 строк текста линейных участков. Следовательно, порядка 10% линейных участков (или дуг в графе) программных модулей могут содержать первоначально ошибки перед тестированием, что соответствует вероятности q i j» 0,l. Использование правил структурного программирования, спецификаций требований на модули и группы программ, а также современной технологии программирования позволяет снизить первичную вероятность ошибок приблизительно на порядок, т.е. до уровня q i j» 0,01. Поэтому оценивание стратегий тестирования и достигаемой при этом корректности целесообразно проводить в диапазоне q i j = 0,1-0,01, соответствующем практически наихудшим и наилучшим значениям вероятностей ошибок в дуге до тестирования. Для простейших оценок можно предположить, что все дуги в графе программы имеют одинаковую длину и эквивалентны по вероятности появления в них ошибок, т.е. q i j = const в начале тестирования модуля. В действительности дуги графов реальных программ содержат различные типы операторов, которые в разной степени подвержены искажениям и ошибкам. Операторы в программе различаются по своей сложности и соответственно по вероятности искажения их программистами в процессе создания программ. В зависимости от типа оператора, в котором допущена первичная ошибка, различаются последствия проявления искажений (вторичные ошибки). Планирование тестирования структуры программных модулей и оценивание их корректности в значительной степени может быть автоматизировано. Если фиксировать маршруты, по которым уже выполнено тестирование, то можно автоматически исключать их из информирования и выдавать на регистрацию тестировщикам только группу маршрутов, подлежащих первоочередной проверке. Эти же данные могут использоваться для автоматического расчета полноты проведенной проверки и для оценивания достигнутой структурной корректности программы по каждому из критериев выбора маршрутов. Рассмотренный анализ структурной корректности программ в пределах модуля, может быть распространен на группы взаимодействующих модулей. В этом случае каждый модуль следует рассматривать как закрытую структуру, характеризующуюся ранее оцененной структурной корректностью. В графе группы взаимодействующих модулей может быть выделена совокупность маршрутов исполнения этой группы и проконтролирована полнота их тестирования. Последовательно укрупняя, выделяемые группы таких модулей снизу вверх, можно упорядоченно их тестировать и оценивать достигнутую структурную корректность групп программ и ПС в целом.
Функционирование любой программы можно рассматривать как обработку потока данных, передаваемых от входа в программу к ее выходу (см. п. 13.1). Входные данные последовательно используются для определения ряда промежуточных результатов вплоть до получения необходимого набора выходных данных. Задача тестирования и анализа потока данных состоит в установлении корректности их обработки и в выявлении ошибок в тестируемой программе. Эта задача может решаться статически - без исполнения программы (анализом по ее тексту) и динамически - путем реального исполнения программы на ЭВМ в машинных кодах при различных исходных данных. Наборы действий по преобразованию исходных данных в выходные могут быть формализованы диаграммами потоков данных (DFD – Data Flow Diagrams). Для этого применяется система графических элементов, содержащих квадратики с описаниями сущностей и номерами, а также соединяющие их стрелки процессов: - внешние сущности – объекты, являющиеся источниками или потребителями информации, идентифицируемые их содержанием и номерами; - процессы, перемещающие объекты от одного действия к другому, преобразующие исходные данные в результирующие; - накопители объектов или данных, где временно они размещаются на хранение; - потоки данных – информация, передаваемая от источника к потребителю. Для построения DFD-диаграмм, формализованы синтаксис и семантика графических элементов: отражающих движение объектов – процедуры программ; описаний внешних сущностей – источников и потребителей данных; их хранения. Рекомендуется вначале определять набор действий, описывающих, что должны выполнять процедуры программы. Затем строить модель окружения – внешние сущности, порождающие процессы и специфическое поведение при обработке данных. Наборы простейших DFD-диаграмм – операторов программы, объединяются в иерархические структуры, отражающие потоки данных в программных модулях или функциональных компонентах из ряда модулей. Данные, участвующие в вычислениях, на языках программирования высокого уровня определены явно по имени, типу, способам доступа и использования. Это позволяет рассматривать программу в виде мультиграфа, заданного структурой передач управления (потоком управления) и графом преобразования данных, участвующих в вычислениях (поток данных). Пересечение потока управления и потока данных осуществляется в операторах ветвления: проверки условий и циклах. Совместный анализ потоков управления и данных позволяет проверять корректность реализации областей определения переменных на маршрутах исполнения программы. Последствия ошибок в программе могут проявляться как малые изменения некоторых переменных в процессе вычислений и как полное искажение или отсутствие на выходе требующихся величин. Тестирование программного модуля целесообразно проводить на упорядоченных наборах данных с учетом степени их влияния на выходные результаты. С этой позиции для последующего анализа целесообразно выделить два вида обработки данных: - полностью изменяющей область определения и значения результатов обработки; - изменяющей результаты в пределах некоторой ограниченной, правильной области определения. Первому виду обработки соответствуют исходные данные в критических точках и на границах областей изменения переменных. При таких критических значениях может изменяться маршрут исполнения программы, вследствие чего возможно наибольшее изменение результатов. Поэтому обычно тестирование обработки данных, прежде всего, направлено на проверку исполнения программ при значениях переменных, влияющих на выбор маршрута и логику функционирования программ (стратегия выделения областей переменных). Граничные условия - это ситуации, возникающие в непосредственной близости к границам областей коренного изменения обрабатываемых переменных. Число таких критических значений каждой переменной может быть на несколько порядков меньше, чем число значений по всей внутренней части области изменений этой величины. Большинство критических значений (предикатов) может существенно влиять на результаты и подлежит наиболее тщательному тестированию. В этой части тестирование обработки данных по содержанию близко к тестированию структуры программы (см. п. 13.4). При этом виде тестирования маршруты формируются в процессе анализа и обработки данных на последовательных операторах условий в тексте программы. Набор сочетаний исходных данных в тестах непосредственно влияет на степень охвата тестированием из полного набора участков программы. Путем сопоставления проверенных маршрутов с маршрутами, выделенными по графу программы при различных критериях можно оценивать достигнутую полноту тестирования модуля и приблизительно степень его корректности. Второму виду обработки соответствуют данные в ограниченной (или неограниченной) области определения, которая может делиться на некоторое множество сопрягающихся областей (подобластей). Изменение данных внутри такой области не влияет на маршрут исполнения программы. Поэтому для проверки функционирования программы из всего множества значений достаточно использовать при тестировании только несколько значений внутри и вблизи границ области. Количество величин, используемых для тестирования при обработке этого вида, может быть на несколько порядков меньше полного числа значений каждой переменной в области. В процессе тестирования проверяется точность осуществляемых вычислений, правильность масштабирования и размерности обрабатываемых величин, корректность формирования логических величин. При этом тестирование должно охватывать всю область изменения каждой обрабатываемой переменной и каждой результирующей величины. При анализе обработки данных в пределах областей их определения методы тестирования целесообразно применять упорядоченно в следующей последовательности: - тестирование при значениях данных, определяющих маршруты исполнения программы (стратегия областей); - тестирование корректности записи и считывания переменных при вычислениях и полноты состава выходных данных на всех маршрутах исполнения программы; - тестирование точности результатов вычислений и корректности обработки каждой переменной; - тестирование на полное соответствие спецификации требований состава, значений и точности выходных данных. В приведенной последовательности частные методы тестирования позволяют, прежде всего, выявлять первичные ошибки, которые способны искажать результаты в наибольшей степени. При ограниченных ресурсах и такой последовательности тестирования в программе могут оставаться ошибки, наименее влияющие на корректность выходных данных. На основе таких проверок может оцениваться степень охвата тестированием всех условий, определенных в спецификации, и дополнительное тестирование следует проводить только при отдельных недостаточно проверенных входных данных. Тестирование при значениях данных, определяющих маршруты исполнения программы (стратегия областей). Маршруты последовательности обработки данных могут зависеть от любых типов анализируемых величин. Одной из задач тестирования является проверка сопоставимости сравниваемых типов величин и идентичности условий их кодирования (разрядности, масштабов). Критические значения - предикаты, влияющие на выбор маршрутов, во многих случаях не являются фиксированными, а формируются при обработке данных и/или сравнении нескольких переменных. При этом предикаты могут образовываться во всей области изменения каждой из переменных, например, когда они оказываются равными или отличаются на некоторую постоянную величину. Предикаты, определяющие выбор маршрутов исполнения программы, могут формироваться в результате вычислений на линейных участках программы. Эти участки в среднем невелики и содержат около 5 - 10 строк текста программы. Каждая ограниченная область исходных данных соответствует определенному маршруту в программе. Граница областиопределяется интерпретациями предикатов по маршруту и состоит из набора участков границы, каждый из которых определяется единственным, простым предикатом, выбирающим дугу маршрута в графе программы. Каждый участок границы области может быть открытым или закрытым в зависимости от оператора условий в предикате. Закрытый участок границы принадлежит ограничиваемой области и формируется предикатами с операторами £, ³ или =. Открытый участок границы не входит в состав области и формируется операторами <, > и ¹. Общее число предикатов в маршруте - это верхний предел числа граничных участков области входных переменных данного маршрута, так как некоторые предикаты маршрута могут в действительности не создавать граничных участков. Такие случаи возникают, когда предикат требуется для нескольких путей, и в некоторых из них повторно анализируется на маршруте. Таким образом, программа по отношению к потоку данных может рассматриваться, прежде всего, как выполняющая разделение пространства исходных данных на области, каждая из которых соответствует одному исполняемому маршруту. Ошибки в программе могут быть обусловлены модификацией границы области определенного маршрута, приводящей к расширению или сужению пространства исходных данных соответствующего маршрута. Кроме того, деформация границ областей может приводить к ошибкам уничтожения некоторых областей и потери соответствующих им маршрутов. Причинами таких ошибок могут быть искажения операторов анализа условий или искажения в процессе вычисления значений предикатов при правильном содержании оператора условия. Искажения операторов анализа условий может приводить как к деформации границы области, так и к появлению новых границ или их уничтожению, вследствие чего могут разделяться или сливаться области. Сложность тестов линейно растет с увеличением размерности пространства исходных данных (числа требований или переменных) и с ростом числа предикатов на маршрутах. Для многих типовых модулей сложность тестов оказывается допустимой для практически полной проверки модуля. Ограничения метода проверки областей могут проявляться при сложных организациях циклов, когда резко возрастает число маршрутов и анализируемых условий. Тестирование корректности определения и использования данных на маршрутах исполнения программы. Если маршруты исполнения программы соответствуют допустимым областям изменения входных данных, то целесообразно проверять корректность основных операций обработки данных на выделенных маршрутах. Каждая величина на маршруте исполнения программы считывается из памяти, и после использования для вычислений записывается в память ЭВМ для хранения и последующей обработки. Чередование операций чтения и записи переменных может быть нарушено в результате ошибок в программе. Для выявления таких ошибок проводится тестирование корректности записи и считывания реальных данных или статический анализ этих операций по исходному тексту программы. Тестирование корректности обработки каждой переменной и точности результатов вычислений. Когда показано, что сочетания данных и их области определения соответствуют корректному формированию маршрутов в программе, а также нет явных ошибок в последовательностях определения и использования каждой переменной, целесообразно провести тестирование корректности обработки каждой переменной и точности вычислительной части программы. Этот вид тестирования производится преимущественно с вещественными и целыми величинами во внутренней части их областей определения при операциях с фиксированной точкой. Кроме того, может выполняться дополнительный контроль точности вычислений при граничных значениях, ранее использовавшихся для тестирования маршрутов по областям определения. Множество тестовых значений для проверки вычислений при простых числовых переменных целесообразно строить упорядоченно с учетом следующих правил: - входные тестовые данные в области гладкого изменения, зависящих от них результатов, должны принимать, по крайней мере, значения, близкие к наибольшим и наименьшим, а также одно-два промежуточных значения; - тестирование должно проводиться при всех особых значениях входных переменных - в точках резкого возрастания или разрыва производных, при нулевых, единичных и предельно малых численных значениях; - входные тестовые значения должны обеспечивать проверку программы при выходных результатах, имеющих особые точки резкого изменения или разрыва производных; - если значения некоторой переменной зависят от значений другой переменной, то их необходимо тестировать при особых значениях сочетаний переменных (равенство обеих переменных, малое и предельно большое их различие, нулевые и единичные значения). Таким образом, для каждой простой числовой переменной, кроме трех точек вблизи и на границе области определения, обычно необходимо тестирование программы в 3 - 4 промежуточных и в 2 - 5 особых точках значений входных данных. При 10 входных переменных и сложных вычислениях в программном модуле для тестирования вычислений может потребоваться до 50 тестовых значений. Группируя и упорядочивая тестовые значения разных переменных, их общее количество можно сократить до 5 - 10 тестовых наборов.
Дата добавления: 2014-01-13; Просмотров: 1207; Нарушение авторских прав?; Мы поможем в написании вашей работы! Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет |