Электронная библиотека диссертаций и авторефератов России
dslib.net
Библиотека диссертаций
Навигация
Каталог диссертаций России
Англоязычные диссертации
Диссертации бесплатно
Предстоящие защиты
Рецензии на автореферат
Отчисления авторам
Мой кабинет
Заказы: забрать, оплатить
Мой личный счет
Мой профиль
Мой авторский профиль
Подписки на рассылки



расширенный поиск

Методы реализации регрессионного тестирования по расширенным тестовым наборам Епифанов Николай Анатольевич

Методы реализации регрессионного тестирования по расширенным тестовым наборам
<
Методы реализации регрессионного тестирования по расширенным тестовым наборам Методы реализации регрессионного тестирования по расширенным тестовым наборам Методы реализации регрессионного тестирования по расширенным тестовым наборам Методы реализации регрессионного тестирования по расширенным тестовым наборам Методы реализации регрессионного тестирования по расширенным тестовым наборам Методы реализации регрессионного тестирования по расширенным тестовым наборам Методы реализации регрессионного тестирования по расширенным тестовым наборам Методы реализации регрессионного тестирования по расширенным тестовым наборам Методы реализации регрессионного тестирования по расширенным тестовым наборам
>

Данный автореферат диссертации должен поступить в библиотеки в ближайшее время
Уведомить о поступлении

Диссертация - 480 руб., доставка 10 минут, круглосуточно, без выходных и праздников

Автореферат - 240 руб., доставка 1-3 часа, с 10-19 (Московское время), кроме воскресенья

Епифанов Николай Анатольевич. Методы реализации регрессионного тестирования по расширенным тестовым наборам : Дис. ... канд. техн. наук : 05.13.11 : Санкт-Петербург, 2003 149 c. РГБ ОД, 61:04-5/1798

Содержание к диссертации

Введение

1. Обзор подходов к регрессионному тестированию 8

1.1. Понятие регрессионного тестирования 8

1.2. Необходимость регрессионного тестирования 12

1.3. Цели и задачи регрессионного тестирования 14

1.4. Классификация изменений кода и методов сопровождения 17

1.4.1. Типы изменений 17

1.4.2. Виды тестирования 19

1.4.3. Виды регрессионного тестирования 21

1.5. Методы выборочного регрессионного тестирования 23

1.5.1. Выборочные методы и метод повторного прогона всех тестов 23

1.5.2. Классификация тестов при отборе 16

1.6. Классификация выборочных методов 29

1.6.1. Полнота, точность, эффективность, универсальность 29

1.6.2. Случайные методы 32

1.6.3. Безопасные методы 33

1.6.4. Методы минимизации 35

1.6.5. Методы, основанные на покрытии кода 37

1.6.6. Сравнение классов методов выборочного регрессионного тестирования 38

1.7. Особые виды регрессионного тестирования 39

1.7.1. Регрессионное тестирование межмодульных зависимостей 39

1.7.2. Регрессионное тестирование объектно-ориентированных программ 40

1.8. Технологии, не связанные с отбором тестов 41

1.8.1. Уменьшение объёма тестируемой программы 41

1.8.2. Методы упорядочения 42

1.8.3. Целесообразность отбора тестов 45

1.8.4. Функции предсказания целесообразности 53

1.9. Обзор методов отбора регрессионных тестов 58

1.10. Выводы 69

2. Методика расширенного регрессионного тестирования 71

2.1. Стандартная методика выборочного регрессионного тестирования 71

2.2. Новый метод отбора тестов 73

2.3. Обоснование корректности метода отбора тестов 77

2.4. Новый метод порождения дополнительных тестов 78

2.5. Условия применимости предложенных методов 81

2.6. Улучшенная методика регрессионного тестирования 83

2.7. Оценка предложенных методов 86

2.7.1. Оценка метода отбора тестов 86

2.7.2. Оценка метода порождения новых тестов 87

3. Система поддержки регрессионного тестирования 91

3.1. Описание системы поддержки регрессионного тестирования 91

3.1.1. Общая структура системы 91

3.1.2. Профайлер 92

3.1.3. Грамматический анализатор 95

3.1.4. Оптимизация работы профайлера 99

3.1.5. Решение прикладных задач с помощью профайлера 101

3.1.6. Приведение множества ДР к универсальному формату 105

3.1.7. Получение списка тестов, подлежащих повторному запуску 109

3.1.8. Определение новых состояний и списка изменённых переменных 109

3.1.9. Создание списка рекомендуемых новых тестов 112

3.1.10. Автоматическое добавление операторов вывода 113

3.2. Известные ограничения системы поддержки регрессионного тестирования 116

3.2.1. Ограничения, связанные с используемыми методами 116

3.2.2. Ограничения, связанные с программной реализацией методов 118

3.2.3. Требования к аппаратной и программной конфигурации ЭВМ 119

3.3. Методика использования системы поддержки регрессионного тестирования 119

3.4. Оценка программной реализации системы 121

4. Результаты применения разработанных методов и средств регрессионного тестирования 124

4.1. Методы и средства регрессионного тестирования программных проектов 124

4.2. Анализ применения разработанных методов и средств 125

4.3. Выводы 134

Заключение 136

Литература 140

Введение к работе

Программы подвержены неизбежным изменениям, как бы хорошо разработаны они ни были первоначально. Их выполнение выявляет дефекты, которые должны быть исправлены. Ошибочные и изменённые требования приводят к переработке программ. Новые области применения старых программ требуют новых функциональных возможностей, не учтённых в требованиях изначально. Контроль над изменениями -критический фактор для сохранения полезности программ [28].

С развитием программного обеспечения сопровождение становится наиболее дорогим компонентом разработки программных систем. Исследования [14, 89, 118] показали, что от 1/2 до 2/3 затрат на протяжении срока службы системы программного обеспечения уходит на сопровождение. На этап сопровождения, к тому же, приходятся и наибольшие затраты в случае внесения ошибок. При анализе самых дорогих ошибок за всю историю программирования [132] было выяснено, что худшие три из них были вызваны изменением ровно одной строки кода, который не был протестирован после внесения изменения.

Стандартный процесс разработки программного обеспечения хорошо работает в случае добавления к системе новых функциональных возможностей; в других аспектах он требует определённой адаптации. Для повторной проверки корректности функциональных возможностей, например, унаследованных из предыдущей версии, в процессе разработки необходимо использовать регрессионное тестирование [58, 71], то есть повторное тестирование части программы, зависящей от внесённых изменений. Регрессионное тестирование успешно применяется как при изменении компонентов систем, так и при добавлении к системе новых компонентов (или функциональных возможностей). Регрессионное тестирование гарантирует, что внесённые в код изменения корректны и не воздействуют неблагоприятно на другие блоки программы; в противном случае считается, что в системе появились регрессионные ошибки [75, 84]. Поведение новой версии программы должно в точности совпадать с поведением старой, за исключением ситуаций, которые обусловлены изменённой функциональностью. Таким образом, регрессионные системные тесты могут рассматриваться как частичные требования к новым версиям системы. Обычно вместо регрессионного тестирования для доказательства того, что качество системы не ухудшилось, запускается множество всех тестов, используемых на системном цикле.

Регрессионное тестирование может быть отнесено к методам профилактического сопровождения, применяемым в ходе модификации программного изделия. Даже в случае, когда программа не требует исправления ошибок, на определённом этапе могут

потребоваться некоторые действия по её адаптации и совершенствованию. Профилактическое сопровождение с применением методов регрессионного тестирования не только устраняет необходимость в дальнейшем сопровождении при исправлении дефектов, но и делает возможным экономию проектных ресурсов за счёт их более гибкого и эффективного использования на этапах сопровождения, интеграционного и системного тестирования. Это позволяет улучшить способность программного изделия адаптироваться к любым изменениям требований без потери гарантированного качества при входе на последнюю фазу жизненного цикла программы [73].

Регрессионное тестирование — дорогостоящий род деятельности: процесс регрессионного тестирования может включать исполнение достаточно большого количества тестов на скорректированной программе, даже если изменений очень мало. Несмотря на то, что усилия, требуемые для внесения небольших изменений, как правило, минимальны, они могут требовать достаточно больших усилий для проверки качества изменённой программы [38, 37]. Тем не менее, проведение регрессионного тестирования необходимо. Надёжная и эффективная разработка и сопровождение программного обеспечения невозможна без регрессионного тестирования [73].

Важным различием между регрессионным тестированием и тестированием в процессе разработки является наличие в процессе регрессионного тестирования готового набора тестов, доступного для повторного использования. Одна из стратегий регрессионного тестирования допускает повторный запуск всех этих тестов, но такой метод потребляет чрезмерно много времени и ресурсов. Альтернативный метод, выборочное повторное тестирование, выбирает из старого набора тесты, которые считает необходимыми для тестирования изменённой программы. Эти тесты дополняются, в случае необходимости, новыми, возможно для того, чтобы удовлетворить некоторый критерий покрытия кода. Однако, как отмечается в работе [85], такой выборочный подход даёт выигрыш только тогда, когда стоимость отбора и прогона подмножества тестов меньше, чем стоимость выполнения тестов, которые удаётся опустить.

Во время, когда система подвергается изменению, трудно определить, какие тесты подлежат модификации и как именно они должны быть изменены [137]. Инструментальные средства поддержки разработки программного обеспечения, успешно применяемые при тестировании, далеко не всегда применимы к регрессионному тестированию. Большинство коммерческих средств автоматизации тестирования обеспечивает не более чем возможность сохранять существующие тесты и запускать их повторно после каждого изменения [103, 44, 124, 125]. У них отсутствует возможность какого-либо автоматического отбора тестов, нет и

инструментов оценки требуемых для регрессионного тестирования затрат [85]. Методики выборочного регрессионного тестирования пока ещё не нашли своего воплощения в промышленных программных средствах, доступных рядовому пользователю.

Методы отбора регрессионных тестов основаны на субъективном выборе подмножества из существующего набора тестов. Если программа не тестируется адекватно существующим набором тестов, то маловероятно, что подмножество этого набора будет адекватным для тестирования изменённой версии программы. Более того, даже если существующий набор тестов был адекватен для тестирования предыдущей версии программы, то он не обязательно будет адекватен для тестирования модифицированной программы. Существующие методы отбора регрессионных тестов сосредоточены только на проблеме отбора тестов из существующего набора, в то время как перспективный универсальный метод регрессионного тестирования не должен ограничиваться исключительно существующими тестовыми наборами [114].

Наконец, существующий подход к регрессионному тестированию [111] не учитывает последних достижений в этой области, оставляя за бортом такие возможности, как уменьшение объёма тестируемой программы, методы упорядочения и функции предсказания целесообразности отбора тестов, так что пользователю не всегда понятны основания, которыми руководствуются при проведении выборочного регрессионного тестирования.

Настоящая работа посвящена созданию методики, позволяющей производить отбор тестов для проведения регрессионного тестирования, а также указывать области исходного кода и группы функциональных требований, для которых необходима разработка дополнительных тестов. Эта методика основывается на профилировании исходного кода системы и анализе путей в графе системы, активируемых отдельными тестами. Она также учитывает возможность применения сопутствующих технологий, в частности, обеспечивающих предсказание целесообразности регрессионного тестирования.

В ходе работы создан программный продукт, автоматизирующий применение разработанной методики. Результирующая система опробована на реальных проектах. Её применение позволяет сократить время работы над проектом и обеспечить выигрыш во времени на этапах системного и финального тестирования, где ввиду близости даты поставки важность экономии времени особенно возрастает.

Для достижения поставленной цели в работе выполнено следующее: 1. Проведён анализ существующих методов и средств регрессионного тестирования ПО и выбор требований к системе.

2. Разработан метод выборочного регрессионного тестирования. Предложенный подход, в терминах [41, 112], является безопасным и целесообразным, то есть способен выбирать 100% тестов, обнаруживающих ошибки, и оправдывать расходы на собственное применение. Он обеспечивает линейный рост времени выполнения тестов в зависимости от объёма тестируемой программы (т.е. является эффективным) и применим для широкого круга программ, написанных на языке С (т.е. является универсальным).

3. Разработан метод порождения дополнительных тестов при регрессионном тестировании. Метод находит ситуации, «подозрительные» с точки зрения возможного наличия ошибок, и рекомендует пути их дальнейшего тестирования. Он применим как для случая модульного тестирования с применением структурных критериев покрытия кода, так и для системного тестирования, ориентированного на требования технического задания.

4. Разработана методика расширенного регрессионного тестирования. Методика учитывает как разработанный метод порождения дополнительных тестов, так и другие наработки последних лет, не учтённые, в частности, в алгоритме Ротермела - Харролд, приведённом в работе [111].

5. Создан инструментарий, поддерживающий процесс автоматизации регрессионного тестирования.

6. Проанализированы результаты применения предложенных методик и инструментального пакета при регрессионном тестировании программных проектов.

Классификация изменений кода и методов сопровождения

На фазе промышленной эксплуатации и сопровождения жизненного цикла приходится иметь дело с изменениями в программном продукте. Изменения служат для исправления ошибок, добавления новых свойств и функциональных возможностей, а также для улучшения эффективности кода программы или использования ресурсов. При изменении программы проводится её повторное тестирование, чтобы удостовериться в корректности изменённого кода и сохранении первоначальной функциональности [130].

Создание автоматизированного программного средства содействия регрессионному тестированию требует наличия классификации изменений программного обеспечения, чтобы сопоставить каждой категории регрессионных тестов набор правил для отбора. В работе [131] эти понятия иллюстрируются с помощью иерархии требований и иерархии тестов.

Изменениям иерархии требований ставятся в соответствие правила изменения тестовой иерархии, что позволяет формировать наборы регрессионных тестов [130].

Оператор считается изменённым, если он был заменён другим оператором (несколькими операторами), был изменён или удалён, или непосредственно после этого оператора был вставлен новый оператор (несколько операторов). С целью дать формальное определение изменений, мы вводим понятие кластеризации - метода автоматической идентификации изменений в программе Р1, которые привели к созданию её новой версии Р2 [82]. Изменения определяются как подграфы направленных графов Р1 и Р2, имеющие один вход и один выход. Каждый кластер затем рассматривается как узел в «упрощённых» направленных графах Р1 и Р2. Эти направленные графы изоморфны по построению, так как установлено взаимно однозначное соответствие между их узлами [83].

Объём, распределение и другие характеристики изменений независимы [47]. Все эти факторы влияют на применение метода отбора [58].

В процессе адаптивного или усовершенствующего сопровождения обычно вводятся новые модули. Чтобы отобразить требуемое усовершенствование или адаптацию, изменяется спецификация системы. В то же время при корректирующем сопровождении, как правило, спецификация не изменяется, и новые модули не вводятся. Большинство модификаций включают только добавление, удаление и изменение операторов. Модификации программы на фазе разработки подобны модификациям корректирующего сопровождения, так как из-за обнаружения ошибки вряд ли потребуется модифицировать спецификацию программы [77, 23]. За исключением редких моментов крупных изменений, на фазе сопровождения изменения системы обычно невелики и производятся с целью устранения проблем или постепенного расширения функциональных возможностей [41].

По типу изменяемого объекта изменения делятся на три основных класса: изменения потока управления, изменения потока данных, и изменения, не затрагивающие ни потока управления, ни потока данных [58].

Иногда устаревшие участки кода удаляются из программы. Старые функциональные возможности остаются в программах для поддержки предыдущих версий. Через какое-то время эти функциональные возможности могут постепенно изыматься. Удаление соответствующего кода из системы программного обеспечения может привести к проблемам, если данное изменение должным образом не протестировано [130].

С точки зрения действий, выполняемых при изменении, существует три типа изменений программ: (1) Добавление новых функциональных возможностей (2) Удаление устаревших функциональных возможностей (3) Изменение функциональных возможностей

Правила порождения регрессионных тестов для случая изменения функциональных возможностей могут быть описаны в терминах удаления функциональных возможностей и добавления "новых" функциональных возможностей. Каждому типу изменений соответствуют специфические правила создания набора регрессионных тестов. Согласно [87], эти правила должны определять существующие тесты для повторного использования и повторного запуска после соответствующего изменения и указывать на потребность в создании новых тестов.

Как ни удивительно, практически ни один из существующих методов выборочного повторного тестирования не учитывает необходимости тестирования удаления кода [111].

Важной характеристикой изменений является их распределение. Например, изменениям могут подвергнуться функции различных типов. Функции ядра обеспечивают главные функциональные возможности библиотеки (программы) и используются практически всеми приложениями (другими функциями), тогда как прикладные функции являются более специализированными и используются реже. Отметим, что функции, требующие наибольшего объёма повторного тестирования, имеют наименьшую вероятность изменения в процессе сопровождения [41]. Кроме того, в любой программе вероятность активации случайно выбранным тестом точки изменения кода, достигаемой при выполнении некоторого условия, меньше, чем вероятность активации точки изменения кода, достижение которой не требует выполнения каких-либо условий [114]. Обобщая, можно сказать, что конкретные местоположения изменений в программе напрямую отражаются на результатах отбора тестов [64].

Обоснование корректности метода отбора тестов

Выборочные стратегии регрессионного тестирования программного обеспечения требуют отбора соответствующего подмножества тестов из числа ранее выполнявшихся. Отбор тестов производится на основании анализа информации об изменениях в системе, приведших к созданию новых версий [35, 41, 52, 65, 69, 87, 88, 99, 113, 126, 106]. Обоснованием подобных стратегий является желание сохранить затраты на регрессионное тестирование под контролем [106].

Предположим, что изменения в программе ограничиваются одним оператором. Если при выполнении какого-либо теста на исходной программе этот оператор никогда не получает управление, можно с уверенностью утверждать, что он не получит управление также и в ходе выполнения теста на новой программе, и вывод новой и старой программы будет совпадать. Следовательно, нет необходимости выполнять этот тест на новой программе. Указанный метод может легко быть обобщён для случая нескольких изменений: если тест не задействует ни одного изменённого оператора, и его входные данные не изменились, код, выполняемый им в изменённой программе, будет в точности таким же, что и в первоначальной версии. В функциональности двух систем нет различий; следовательно, нет необходимости повторно прогонять тест [28].

Если тест не затрагивает функций, чьё видимое поведение изменилось в результате модификации кода, это означает, что, несмотря на изменения в программе, все операторы, которые получают управление при выполнении этого теста, не отразятся на выводе системы. Другими словами, выходные данные каждого теста будут точно такими же, как у первоначальной системы. Таким образом, нет необходимости повторно прогонять и такие тесты [143].

Перечислим некоторые наблюдения, важные для проведения регрессионного тестирования, (і) Некоторые участки кода программы не получают управление при выполнении некоторых тестов, (ii) Если участок изменённого кода не получает управление при выполнении теста, он не может воздействовать на значения выходных данных программы при выполнении данного теста, (iii) Тот факт, что участок изменённого кода получает управление при выполнении теста, не всегда отражается на выходных данных программы при выполнении данного теста. Действительно, если изменяется первый блок программы, например, путём добавления инициализации переменной, изменяются и все пути в программе, и, как следствие, большинство методов отбора тестов будет рекомендовать выполнение всех тестов набора. Однако может так случиться, что только небольшое подмножество тестов задействует пути, где действительно используется значение этой инициализированной переменной [35,36]. (iv) Если тест t eT активирует участок кода программы, через который проходит путь, проходящий также и через изменённый код, это не обязательно означает, что tk будет активировать этот изменённый код. (v) Участок кода программы, через который проходит путь, проходящий также и через изменённый код, может не воздействовать на значения выходных данных программы, связанных с функциональными возможностями, обеспечиваемыми изменённым кодом [30]. (vi) Не всегда каждый оператор программы воздействует на каждый элемент её выходных данных [28]. Эти наблюдения позволяют ориентироваться на выбор только тех тестов, чьи релевантные сектора относятся к изменённому требованию (требованиям) и воздействуют на вывод программы по отношению к рассматриваемому изменению (изменениям). При этом гарантируется, что будут выбраны только тесты, обнаруживающие изменения, и метод будет, как говорят, точным [113, 30]. Таким образом, применение метода покрытия точек использования неисполняемых определений является обоснованным.

Подавляющее большинство программных продуктов, находящихся в промышленном использовании, рассчитано на обработку последовательностей входных данных неограниченной длины. Элементами таких последовательностей могут служить, например, строки текстового файла, события операционной системы или нажатия клавиш клавиатуры. Сценарий работы с программой такого рода состоит из последовательности транзакций. Выполнение транзакции приводит к изменению состояния программы; в результате некоторых транзакций происходит завершение работы программы. Тесты для таких программ также представляют собой последовательность транзакций. Большинство таких тестов легко может быть расширено путём добавления дополнительных транзакций в список.

Развитие программного продукта от версии к версии влечёт за собой появление новых состояний. В существующих системах автоматизации тестирования анализу этих состояний не уделяется внимания. Между тем, они могут служить источником ошибок, являясь ошибочными как сами по себе, так и находясь на пути, ведущем к одному из ошибочных состояний. Проблемы такого рода могут быть решены в рамках задачи реализации регрессионного тестирования на этапе выбора стратегии. Предлагается к использованию новая технология комбинаторных методов, предусматривающая создание новых тестов как суперпозиции уже имеющихся, с учётом информации об изменении состояния тестируемой программы в результате прогона теста. Этот подход позволяет указать, какого рода новые тесты с наибольшей вероятностью обнаружат ошибки. Как и в 2.2, обозначим тестируемую программу Р, а множество её тестов Т = {ti, t2,... , t„}, где tj - отдельный тест. Введём понятие состояния тестируемой программы s как совокупности значений некоторого подмножества глобальных и локальных переменных. При создании новых тестов будем рассматривать состояния программы перед запуском теста (so) и после его окончания (Sj). Информацию об этих состояниях необходимо собирать для каждого теста по результатам запуска на предыдущей версии продукта. В таком случае, методика порождения новых тестов при регрессионном тестировании на основе анализа «подозрительных» состояний сводится к следующей последовательности шагов: 1. Вычисляется список глобальных и локальных переменных, определяющих состояние программы s. 2. С помощью анализа профиля программы, полученного на предыдущей версии продукта і - 1, для каждого существующего теста tj собирается информация о состояниях программы перед запуском теста и после его окончания (т.е. so и Sj). Множество таких состояний обозначается S,. і: 3. Новые и выбранные регрессионные тесты (тесты из множества Т ) выполняются на текущей версии продукта і. По аналогии с Si _ і вычисляется множество Sj, которое сохраняется под управлением системы контроля версий. 4. Множество новых по сравнению с предыдущими версиями состояний Nj является «подозрительным» с точки зрения наличия ошибок. Правило вычисления множества Nj описывается следующей формулой: Ni=Sj\Si.i 5. Если множество Nj включает состояния, в которых дальнейшая работа продукта невозможна по спецификации, необходимо проанализировать, создаются ли они в результате выполнения тестов, проверяющих нештатные режимы работы продукта, или каких-либо других тестов. В последнем случае фиксируется ошибка. 6. Нештатные состояния исключаются из множества Nj. 7. Если новых состояний, допускающих продолжение выполнения программы, не обнаружено, т.е. N; = 0, перейти к шагу 10. 8. Для каждого состояния множества Nj вычисляется вектор его отличия от исходного состояния So, т.е. переменные, изменённые по сравнению С So. 9. С учётом информации об изменённых переменных модифицируется множество изменённых строк исходного кода ДР и используется какая-либо методика отбора тестов для выборочного регрессионного тестирования. 10. Шаги 3-9 выполняются повторно до достижения состояния Nj = 0 либо до истечения времени, отведённого на регрессионное тестирование. Руководствуясь методом разбиения на классы эквивалентности, инженер, ответственный за тестирование, может также принять решение о прекращении цикла тестирования, если ни один тест из созданных на очередном этапе не принадлежит к новому классу эквивалентности.

Определение новых состояний и списка изменённых переменных

После запуска всех тестов на изменённой версии программы со вставленными контрольными печатями проводится анализ результирующих состояний программы. На вход соответствующего модуля подаётся множество корректных состояний программы, наблюдавшихся при тестировании её предыдущих версий. Формат файла, содержащего данное множество, приводится на рис. 3.18. Первое поле - это имя теста; далее идут имена переменных и их значения, разделённые знаком = . Поскольку в ходе выполнения теста цикл обработки событий может получать управление неоднократно, некоторым тестам соответствует несколько строк. Обратим внимание на значение переменной S в первой строке, соответствующей тесту 1_1. Можно видеть, что к моменту входа в цикл переменная ещё не инициализирована; в общем случае, это может приводить к ошибкам. На выходе модуля получается обновлённое множество состояний в том же формате, а также множество переменных, изменённых по сравнению с корректным состоянием после выполнения некоторого теста. Решение задачи требует рассмотрения процесса выполнения каждого теста на текущей версии программы. Была разработана методика определения новых состояний и списка изменённых переменных, которая сводится к следующей последовательности шагов: 1) Рассматривается файл, в который профайлером были сохранены состояния программы в ходе выполнения теста. Подсчитывается число сохранённых состояний, соответствующее количеству проходов по функции обработки событий, и число отдельных переменных. 2) Для каждого состояния конструируется строка, состоящая из имени теста, имён переменных и их значений в данном состоянии. 3) Создаётся массив таких строк; одинаковые строки исключаются из массива, даже если они соответствуют разным тестам. 4) Из входного файла считывается аналогичный массив, полученный на предыдущей версии программы. 5) Для каждого состояния новой версии программы производится поиск его аналога в исходной версии программы. Если аналогов не обнаружено, состояние является новым и добавляется к массиву. 6) Из файлов состояния программы, сохранённых профайлером на предыдущей версии, выбирается файл, соответствующий исследуемому тесту. Формируется список значений переменных по завершении этого теста. 7) Если значение какой-либо переменной на новой версии программы не совпадает с её значением на старой, имя этой переменной выводится в файл. Переменные объединяются по строкам, соответствующим отдельным тестам; первым элементом такой строки является имя исследуемого теста. В скобках указывается порядковый номер прохода по циклу обработки событий. 8) В другой выходной файл выводится обновлённое множество состояний. Пример файла, содержащего множество изменённых переменных, приведён на рис. ЗЛО, пример файла состояний программы приводится на рис. 3.18. С алгоритмом работы модуля можно ознакомиться по рис. 3.19.

В результате работы модуля, описанного в 3.1.8, создаётся файл, где каждому тесту ставятся в соответствие переменные, изменившиеся в результате его выполнения (см. рис. 3.10). В результате работы одной из подсистем профайлера изменившиеся состояния связываются с существующими тестами, которые, будучи запущены из этих состояний, могли бы проверить их корректность. Эти данные хранятся в формате рис. 3.17. Для сведения всей этой информации к более удобному виду предусмотрен ещё один модуль.

Каждой строке файла изменённых переменных соответствует файл n.txt, где п — порядковый номер строки. Для каждого такого файла заводится список тестов, которые необходимо запустить после изменения переменных в соответствующей строке; изначально этот список пуст. Каждая строка файла n.txt интерпретируется как имя теста и добавляется к списку. Если в списке уже есть такой тест, добавляется пустая строка. Таким способом создаётся множество последовательностей из двух тестов, где первый тест - это первый элемент строки файла изменённых переменных, а второй тест выбирается из списка. Эти последовательности выводятся в файл. Пример такого файла приведён на рис. 3.20. Каждая строка файла соответствует одному рекомендованному новому тесту, состоящему из двух старых, выполняемых последовательно. Строка начинается с имени старого теста, выполняемого первым; в скобках указывается номер прохода по циклу обработки событий, на котором выполнение первого теста следует прервать и перейти ко второму. Имя второго теста находится в той же строке, отделённое знаком + . Схема алгоритма модуля изображена на рис. 3.21.

Наличие в составе системы рассмотренного модуля позволяет создавать новые тесты при функциональном регрессионном тестировании в соответствии с методом «подозрительных» состояний.

Анализ применения разработанных методов и средств

С целью оценки предложенного метода отбора тестов проводилась проверка его поведения в условиях наличия изменений различного объёма. Было также проведено его сравнение с другими известными методами. Результаты исследования приводятся на рис. 4.2.

Внесение изменений осуществлялось в соответствии с различными вариациями функциональных требований. Изменения оказывали влияние и на поток управления программы и на её поток данных. Ввиду того, что время исполнения одного теста намного превышало время работы системы поддержки регрессионного тестирования, значение порога целесообразности оказалось равным 1480, т.е. очень близким к 1510 — общему количеству тестов в наборе. Применение функции предсказания целесообразности показало, что среднее количество выбранных тестов должно составить 497, то есть отбор тестов целесообразен. В этих условиях проводилось сравнение метода минимизации, случайного метода и метода повторного прогона всех тестов с предложенным в данной работе методом покрытия точек использования неисполняемых определений.

Из графика видно, что чем больше было сделано изменений в исходном коде продукта, тем большее количество регрессионных тестов требовалось для их покрытия с помощью детерминированного выборочного метода. Предложенный метод покрытия точек использования неисполняемых определений показывает приемлемую производительность и на большей части рассмотренного интервала позволяет экономить средства за счёт сокращения времени на тестирование. Другой детерминированный метод, метод минимизации, позволяет добиться ещё более впечатляющего сокращения объёма набора тестов, но, как указано в 1.6.4, не является безопасным и не может быть рекомендован для широкого круга проектов. Случайный метод позволяет добиться результатов, сходных с результатами метода минимизации, но не требует никаких затрат на анализ при отборе тестов. Этот метод также не является безопасным и на практике может составлять

конкуренцию только методу минимизации. Наконец, метод повторного прогона всех тестов является безопасным, но в большинстве случаев не позволяет экономить средства так, как метод покрытия точек использования неисполняемых определений. В рассмотренном примере рекомендуется применять метод покрытия точек использования неисполняемых определений при объёме изменений до 0.02% от общего объёма кода и метод повторного прогона всех тестов при объёме изменений свыше 0.03%. При объёме изменений от 0.02% до 0.03% можно использовать любой из этих методов.

Сделанные наблюдения позволяют рекомендовать разработанный метод к использованию при регрессионном тестировании проектов того же класса, что и рассмотренный в примере, а именно для проектов, объём кода которых составляет 100 KLOC и более, а количество тестов в наборе превышает 10 .

С целью выяснить, как на характеристики отбора тестов влияет исходное количество тестов в наборе, были проведены исследования, результаты которых отражены на рис. 4.3.

Объём изменений в процессе исследований сохранялся на постоянном уровне. Общая проверяемая функциональность для всех наборов тестов также оставалась неизменной. За основу было взято множество исходных тестов, и затем производилось последовательное слияние этих тестов тремя разными способами. Исследование графика позволило сделать вывод, что с уменьшением количества тестов в регрессионном наборе для одинаковых изменений обычно отбирается больший процент тестов. Действительно, если объединить тест, активирующий изменённый код, и тест, выполняющий только код, который не изменился, получившийся в результате объединения тест должен будет быть отобран для повторного выполнения, то есть фактически необходимо будет выполнить два теста вместо одного. Таким образом, можно сделать вывод, что для целей регрессионного тестирования выгоднее использовать наборы, состоящие из большого числа тестов.

Предложенный в работе метод порождения новых тестов был исследован на предмет вычисления зависимости между объёмом изменений и числом рекомендованных новых тестов (рис. 4.4). Для проведения этого исследования использовался тот же набор изменений, что и для графика на рис. 4.2. Легко заметить, что в исследуемой системе для данных (небольших) объёмов изменений возникновение новых ситуаций не зависит от объема измененного кода. Изменения в коде программного продукта, не превышающие 0.1% от его объёма, приводят к одинаковым изменениям в его состоянии. Наличие случайных выбросов может показывать, что некоторые переменные в системе используются без предварительной инициализации. Таким образом, метод регрессионного тестирования по расширенным тестовым наборам позволяет не только определить множество необходимых регрессионных тестов, но и может указать потенциально опасные места в программе.

В результате анализа «подозрительных» ситуаций порождаются новые тесты, выполнение которых может привести к возникновению новых «подозрительных» ситуаций. Важно убедиться, что для реальных проектов данный процесс сходится, т.е. на некотором шаге «подозрительных» ситуаций не окажется. Чтобы выяснить, соответствует ли это оптимистическое предположение действительности, были проведены дополнительные исследования (рис. 4.5). Вертикальными стрелками обозначены этапы редукции множества тестов.

Корректирующие действия заключаются в анализе полученных тестов и удалении заведомо одинаковых тестовых последовательностей. Одинаковые последовательности могут получаться, если в ходе выполнения разных тестов возникают одинаковые состояния. На данный момент система не определяет автоматически такие ситуации, поэтому требуется вмешательство инженера, ответственного за тестирование. Отметим, что таким способом удаётся добиться значительного уменьшения числа дополнительных тестов, что оказывает влияние и на сходимость алгоритма. Общее количество дополнительных тестов, порождаемых на всех этапах, оказалось незначительным (48) по сравнению с исходным количеством тестов (1510), поэтому целесообразным представляется применение метода упорядочения с дальнейшим прогоном такого количества тестов, которое допустимо в соответствии с графиком проекта. Можно сделать вывод, что процесс итеративного применения метода «подозрительных» состояний сходится, и что применение этого метода не сказывается отрицательно на сроках поставки, поскольку за счёт упорядочения тестов прерывание цикла тестирования возможно в любой момент.

Похожие диссертации на Методы реализации регрессионного тестирования по расширенным тестовым наборам