Добавил:
ivanov666
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз:
Предмет:
Файл:Методы тестирования и отладки программного обеспечения. Учебник
.pdf
Вернемся к примеру регрессионного тестирования функции
решения квадратного уравнения (подраздел 6.5). Случайный метод, такой как random(40), может отобрать для повторного выполнения 2 любые теста из 5. Например, если будут выбраны
тесты 4 и 5, изменения формата вывода на экран не будут протестированы вовсе, что вряд ли может устроить разработчика.
При использовании другого случайного метода – метода экспертных оценок – в данном случае наиболее вероятен выбор всех
тестов, так как затраты на прогон невелики. Однако при регрессионном тестировании больших ПО, когда повторный прогон
всех тестов неприемлем, эксперт вынужден отсеивать некоторые
тесты, что также может приводить к тому, что часть изменений
не будет протестирована полностью.
6.7.2. Безопасные методы отбора тестов
Метод выборочного регрессионного тестирования называется
безопасным, если при некоторых четко определенных условиях
он не исключает тестов (из доступного набора тестов), которые
обнаружили бы ошибки в измененной программе, т.е. обеспечивает выбор всех тестов, обнаруживающих изменения. Тест называется обнаруживающим изменения, если его выходные данные
при прогоне на P′ отличаются от выходных данных при прогоне
на P: P(t) ≠ P′(t). Тесты, активизирующие измененный код, называются выполняющими изменение.
Выбор всех выполняющих изменение тестов является безопасным, но при этом отбираются некоторые тесты, не обнаруживающие изменений. Безопасный метод может
включать в T′
подмножество тестов, выходные данные которых для P и P′ ни
при каких условиях не отличаются. Поскольку не существует
методики, кроме собственно выполнения теста, позволяющей
для любой P′ определить, будут ли выходные данные теста различаться для P и P′, ни один метод не может быть безопасным
и абсолютно точным одновременно. Подмножество T′ является
безопасным подмножеством T тогда и только тогда, когда
P(t) ≠ P′(t) ⇒ t ∈ T′.
Если P и P′ выполняются в идентичных условиях и T′ является безопасным подмножеством T, исполнение T′ на P′ всегда об-
111

наруживает любые связанные с изменениями ошибки в P, которые могут быть найдены путем исполнения T. Если существует
тест, обнаруживающий ошибку, безопасный метод всегда находит ее. Таким образом, ни один случайный метод не обладает такой же эффективностью обнаружения ошибок, как безопасный
метод.
При некоторых условиях безопасные методы в силу определения безопасности гарантируют, что все обнаруживаемые ошибки будут найдены. Поэтому относительная эффективность всех
безопасных методов равна эффективности метода повторного
прогона всех тестов и составляет 100 %. Однако их абсолютная
эффективность падает с увеличением интервала тестирования.
Отметим, что безопасный метод действительно безопасен только
в предположении корректности исходного множества тестов T,
т.е. когда при выполнении всех t ∈ T исходная программа P завершилась с корректными значениями выходных данных, а все
устаревшие тесты были из T удалены.
Существуют программы, измененные версии и наборы тестов, для которых применение безопасного отбора не дает
большого выигрыша в размере набора тестов. Характеристики исходной программы, измененной версии и набора тестов
могут совместно или независимо воздействовать на результаты отбора тестов. Например, при усложнении структуры программы вероятность активации произвольным тестом произвольного изменения в программе уменьшается. Безопасный
метод предпочтительнее выполнения всех тестов набора тогда и только тогда, когда стоимость анализа
имость выполнения
невыбранных тестов. Для некоторых
меньше, чем сто-
систем, критичных с точки зрения безопасности, стоимость
пропуска ошибки может быть настолько высока, что небезопасные методы выборочного регрессионного тестирования использовать нельзя.
Примером безопасного метода может служить метод, который
выбирает из T каждый тест, при выполнении которого проверяется, по крайней мере, один оператор, добавленный или измененный в P′ или удаленный из P. Применение этого метода для
регрессионного тестирования функции решения квадратного
уравнения потребует построения матрицы покрытия, пример
112

которой приведен на рис. 6.3. Следует отметить, что матрица
покрытия соответствует исходной версии программы, поскольку аналогичная информация для новой версии программы пока
не собрана. Звездочка в ячейке таблицы означает, что соответствующий тест покрывает определенную строку кода, если тест
не покрывает строку кода, ячейка оставлена пустой. Строки, измененные по отношению к исходной версии, выделены цветом.
Легко заметить, что в соответствии с требованиями предложенного безопасного метода для повторного выполнения должны
быть отобраны тесты 1, 2 и 5.
6.7.3. Методы минимизации отбора тестов
Процедура минимизации набора тестов ставит целью отбор
минимального (в терминах количества тестов) подмножества
T,
необходимого для покрытия каждого элемента программы, зависящего от изменений. Для проверки
корректности программы
используются только тесты из минимального подмножества.
Рис. 6.3. Матрица покрытия тестируемого кода
Обоснование применения методов минимизации состоит в сле-
дующем:
– корреляция между эффективностью обнаружения ошибок
и покрытием кода выше, чем между эффективностью обнаружения ошибок и размером множества тестов. Неэффективное те-
113

стирование, например многочасовое выполнение тестов, не увеличивающих покрытие кода, может привести к ошибочному
заключению о корректности программы;
– независимо от способа порождения исходного набора тестов,
его минимальные подмножества имеют преимущество в размере
и эффективности, так как состоят из меньшего количества тестов, не ослабляя при этом способности к обнаружению ошибок
или незначительно снижая ее;
– вообще говоря, сокращенный набор тестов, отобранный при
минимизации, может выявлять ошибки, не обнаруживаемые сокращенным набором того же размера, выбранным случайным
или каким-либо другим способом. Такое преимущество минимизации перед случайными методами в эффективности является закономерным. Однако из всех детерминированных методов
минимизация приводит к созданию наименее эффективных наборов тестов, хотя и самых маленьких. В частности, безопасные
методы эффективнее методов минимизации, хотя и намного дороже.
Минимизация набора тестов требует определенных затрат
анализ. Если стоимость этого анализа больше затрат на выпол-
на
нение некоторого порогового числа тестов, существует более дешевый
случайный метод, обеспечивающий такую же эффектив-
ность обнаружения ошибок.
Хотя минимальные наборы тестов могут обеспечивать структурное покрытие измененного кода, зачастую они не являются
безопасными, поскольку, очевидно, что некоторые тесты, потенциально способные обнаруживать ошибки, могут остаться за
чертой
дает избыточностью в том смысле, что никакие два теста
крывают одни и те же
исходно создавались по критерию структурного покрытия,
нимизация приносит плоды, но когда имеем дело с функцио-
отбора. Набор функциональных тестов обычно не обла-
не по-
функциональные требования. Если тесты
ми-
нальными тестами, предпочтительнее не отбрасывать тесты, потенциально способные обнаруживать ошибки. В существующей
практике тестирования инженеры предпочитают не заниматься
минимизацией набора тестов.
Многие критерии покрытия кода фактически не требуют
выбора минимального
множества тестов. В некотором смысле,
114

о безопасных стратегиях и стратегиях минимизации можно думать как о находящихся на двух полюсах
множества стратегий.
На практике использование «почти минимальных» наборов тестов может быть удовлетворительным. Стремление к сокращению объема набора тестов основано на интуитивном предположении, что неоднократное повторное выполнение кода в ходе
модульного тестирования «расточительно». Однако усилия, тре-
буемые для
минимизации набора тестов, могут быть существен-
ны и, следовательно, не оправдывать затрат. Отметим, что большинство стратегий
выборочного регрессионного тестирования,
описанных в литературе, не зависит от критерия покрытия, возможно, использовавшегося при создании исходного набора тестов. Инженеры, занимающиеся регрессионным тестированием,
часто не имеют информации о том, как разрабатывался исходный набор тестов.
Обнаружение ошибок важно для приложений, где
выполнения тестов очень высока, в то время как
стоимость
стоимость про-
пуска ошибок считается незначительной. В этих условиях использование
они связаны с
применения
T не менее одного теста для каждого оператора программы,
из
добавленного или измененного при создании
методов минимизации целесообразно, поскольку
отбором небольшого количества тестов. Примером
методов минимизации служит метод, выбирающий
P′.
В таблице на рис. 6.3 для случая регрессионного тестирова-
ния функции
Equation данный метод ограничится отбором одно-
го теста – теста 2, так как этот тест покрывает обе измененные
строки.
6.7.4. Методы отбора тестов, основанные
покрытии кода
на
Значение методов, основанных на покрытии кода, состоит в том,
что они гарантируют сохранение выбранным набором тестов требуемой степени покрытия элементов
го критерия структурного покрытия
P′ относительно некоторо-
C, использовавшегося при
создании первоначального набора тестов. Это не означает, что
атрибут программы, определенный C, покрывается первона-
если
чальным множеством тестов, он будет также покрыт и выбран-
115

ным множеством; гарантируется только сохранение процента
покрываемого кода.
ют разброс по покрытию, требуя
Методы, основанные на покрытии, уменьша-
отбора тестов, активирующих
труднодоступный код, и исключения тестов, которые только дублируют покрытие. Поскольку на практике критерии покрытия
кода обычно применяются для
каждого покрываемого элемента,
отбора единственного теста для
подходы, основанные на покры-
тии кода, можно рассматривать как специфический вид методов
минимизации
Сравнение методов
.
Таблица 6.3
выборочного регрессионного тестирования
Характеристика
метода
Полнота, % От 0 до 100 100 < 100 < 100
Размер набора
тестов
Время выполнения
метода
Перспективные
свойства методов
регрессионного
тестирования
Случайные
Настраива-
ется
Пренебрежи-
мо мало
Отсутствие
средства
поддержки
регрессион-
ного тестиро-
вания
ла етодов
Безопас-
ные
Большой Небольшой
Значитель-
ное
Высокие
требования
по каче-
ству
Минимиза-
ции
Значитель-
ное
Стоимость
пропуска
ошибки не-
велика
Покрытия
Зависит от
параметров
метода
Значительное
Набор исход-
ных тестов
создается по
критерию по-
крытия
Разновидностью методов, основанных на покрытии кода, явля-
методы, которые базируются на покрытии потока данных.
ются
Эти методы эффективнее
эффективны, как
безопасные методы. В то же время, они могут
требовать, по крайней мере, такого же времени на
и наиболее эффективные
могут обходиться дороже
других
методов минимизации. Они имеют тенденцию к вклю-
методов минимизации и почти столь же
анализ, как
безопасные методы и, следовательно,
безопасных методов и намного дороже
чению избыточных тестов в набор регрессионных тестов для
покрытия зависящих от изменений пар определения/использования, что в некоторых случаях ведет к большому числу отобранных тестов. Этот факт зафиксирован экспериментально.
116

Методы, основанные на использовании потока данных, могут
быть полезны и для других
кроме
отбора тестов, например, для нахождения элементов P, не-
достаточно тестируемых
Метод стопроцентного покрытия измененного кода аналогичен
методу минимизации. Результаты сравнения методов выборочного регрессионного тестирования приведены в табл. 6.3.
задач регрессионного тестирования,
T′.
Контрольные вопросы
1. Каковы цели и задачи регрессионного тестирования про-
граммного обеспечения?
2. Какие существуют виды регрессионного тестирования?
3. В чем суть управляемого регрессионного тестирования?
4. Какова классификация тестов при отборе?
5. Что такое жизненный цикл теста?
6. В чем суть повторного использования тестов?
7. Каковы критерии выборочных методов регрессионного те-
стирования?
8. Какие существуют разновидности метода отбора тестов?
9. В чем суть случайных методов отбора тестов?
10. В чем суть безопасных методов отбора тестов?
11. В чем суть методов минимизации отбора тестов?
12. В чем суть методов покрытия кода отбора тестов?
117

7. МЕТОДЫ И СРЕДСТВА ОТЛАДКИ
ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ
7.1. Обзор ошибок, обнаруживаемых
при отладке программ
Отладка программы является одним из самых сложных про-
цессов разработки ПО и требует глубокого знания:
– специфики управления используемыми техническими сред-
ствами;
– операционной системы;
– среды и языка программирования;
– реализуемых процессов;
– природы и специфики различных ошибок;
– методик отладки и соответствующих программных средств.
Отладка – это процесс локализации и исправления ошибок,
обнаруженных при тестировании ПО. Локализацией называют
процесс определения оператора программы, выполнение которого вызвало нарушение нормального вычислительного процесса. До исправления ошибки необходимо установить ее причину,
т.е. определить оператор или фрагмент, содержащие ошибку.
Причины ошибок могут быть как очевидны, так и очень глубоко
скрыты.
В целом сложность отладки обусловлена следующими причи-
нами:
– требование от программиста глубоких знаний специфики
управления используемыми техническими средствами, операционной системы, среды и языка программирования, реализуемых процессов, природы и специфики различных ошибок, методик отладки и соответствующих ПО;
– психологический дискомфорт, так как необходимо искать
собственные ошибки и, как правило, в условиях ограниченного
времени;
– возможное взаимовлияние ошибок в разных частях про-
граммы, например, за счет затирания области памяти одного модуля другим из-за ошибок адресации;
– отсутствие четко сформулированных методик отладки.
В соответствии с этапом обработки программы, на котором
проявляются ошибки, различают:
118

– синтаксические ошибки – ошибки, фиксируемые компиля-
тором (транслятором, интерпретатором) при выполнении синтаксического и частично семантического анализа программы;
– ошибки компоновки – ошибки, обнаруженные компонов-
щиком (редактором связей) при объединении модулей программы;
– ошибки выполнения – ошибки, обнаруженные операцион-
ной системой, аппаратными средствами или пользователем при
выполнении программы.
Синтаксические ошибки относят к группе самых простых,
так как синтаксис языка, как правило, строго формализован, и
ошибки сопровождаются развернутым комментарием с указанием ее местоположения. Определение причин таких ошибок, как
правило, труда не составляет, и даже при нечетком знании правил языка за несколько прогонов удается удалить все ошибки
данного типа.
Следует иметь в виду, что чем лучше формализованы правила синтаксиса языка, тем больше ошибок из общего количества может выявить компилятор и, соответственно, меньше ошибок будет обнаружено на следующих этапах. В связи
с этим говорят о языках программирования с защищенным
синтаксисом и с незащищенным синтаксисом. К первым,
безусловно, можно отнести язык Pascal, имеющий очень простой и четко определенный синтаксис, хорошо проверяемый
при компиляции программы, ко вторым – язык C со всеми его
модификациями.
Ошибки компоновки, как следует из названия, связаны с проблемами, обнаруженными при разрешении внешних ссылок.
Например, предусмотрено обращение к подпрограмме другого модуля, а при объединении модулей
данная подпрограмма
не найдена или не стыкуются списки параметров. В большинстве случаев ошибки такого рода также удается быстро локализовать и устранить.
К самой непредсказуемой группе относятся ошибки выполнения. Прежде всего они могут иметь разную природу и, соответственно, по-разному проявляться. Часть ошибок обнаруживается и документируется операционной системой. Выделяют
четыре способа проявления таких ошибок:
119

1) появление сообщения об ошибке, зафиксированной схемами контроля выполнения машинных команд, например, переполнение разрядной сетки, ситуация «деление на ноль», нарушение адресации и т.п.;
2) появление сообщения об ошибке, обнаруженной операционной системой, например, нарушение защиты памяти, попытка
записи на устройства, защищенные от записи, отсутствие файла
с заданным именем и т.п.;
3) «зависание» компьютера как простое, когда удается завершить программу без перезагрузки операционной системы, так и
«тяжелое», когда для продолжения работы необходима перезагрузка;
4) несовпадение полученных результатов с ожидаемыми результатами.
Причины ошибок выполнения очень разнообразны, поэтому
их локализация может оказаться крайне сложной. Все возможные причины ошибок можно разделить на следующие группы:
– неверное определение исходных данных;
– логические ошибки;
– накопление погрешностей результатов вычислений.
Классификация ошибок выполнения представлена
на рис. 7.1. Неверное определение ИД происходит, если возникают любые ошибки при выполнении операций ввода-вывода: при
передаче, преобразовании, перезаписи данных. Причем использование специальных технических средств и программирование
с защитой от ошибок позволяют обнаружить и предотвратить
только часть этих ошибок.
Логические ошибки имеют разную природу. Так, они могут
следовать из ошибок, допущенных при проектировании, например, при выборе методов, разработке алгоритмов или определении структуры классов, а могут быть непосредственно внесены
при кодировании модуля.
К ошибкам кодирования модуля относятся ошибки:
некорректного использования переменных;
–
– вычислений;
– межмодульного интерфейса и др.
К ошибкам
некорректного использования переменных отно-
сятся:
– неудачный выбор типов данных;
120
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]
