Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Методы тестирования и отладки программного обеспечения. Учебник

.pdf
Скачиваний:
0
Добавлен:
07.09.2026
Размер:
2 Мб
Скачать
☆
Вернемся к примеру регрессионного тестирования функции решения квадратного уравнения (подраздел 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
Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]