Файл: Отладка и тестирование программ: основные подходы и ограничения (РАЗРАБОТКА ПРОГРАММ).pdf
Добавлен: 30.03.2023
Просмотров: 242
Скачиваний: 2
СОДЕРЖАНИЕ
1.4. Понятие тестирования
Долгое время считалось, что основной задачей тестирования является доказательство отсутствия ошибок в программном коде. Данный взгляд подвергается критике в силу того, что полный перебор всех возможных сценариев находится за пределами вычислительных мощностей.
В настоящее время тестированием называется процесс исполнения программного кода с целью обнаружения ошибок [15].
Понятие тестирования тесно связано с понятием отладки - исправлением ошибок в программном коде. Поэтому первый вопрос, на который должен ответить программист: в каком случае в программе есть ошибка?
Важно понимать, что программа содержит ошибку в том случае, когда она ведет себя неразумно с точки зрения пользователя этой программы. Для этого важно предусмотреть следующие моменты:
- программа должна быть синтаксически корректна – в процессе трансляции не должны быть выявлены ошибки;
- программа должна правильно решать поставленную задачу – при вводе корректных данных программа должна выдавать правильный результат. Правильность результата при этом определяется заказчиком программы;
- программа не должна делать ничего лишнего;
- результат должен получаться за разумное время при разумных затратах прочих ресурсов;
- программа должна правильно реагировать на ввод некорректных данных, заранее предусматривая все исключительные ситуации [14].
На протяжении долгого времени основным способом тестирования являлся метод «черного ящика», при котором на вход программе подавались некоторые данные, а затем проверялся полученный результат. При этом неважно как именно работает программа. Важно отметить, что при таком подходе необходимо иметь спецификацию программы для того, что было с чем сравнивать полученные результаты.
Данный подход применим и сегодня, однако, он обладает рядом недостатков:
- метод «черного ящика» не позволяет обнаружить взаимоуничтожающиеся ошибки;
- не все ошибки воспроизводятся стабильно, поэтому они могут быть не выявлены в результате тестирования [10].
Существование подобных недостатков послужило появлению новых способов тестирования, учитывающих внутреннее устройство программы. Подобные методики получили название тестирования «белого ящика». Примерами данных методик являются: обзор кода, инспекция, аудит, критический анализ и т.д.
В таблице 1 приведены показатели эффективности различных методов тестирования [3].
Из таблицы видно, что тестирование достигает максимального эффекта в тех случаях, когда программа проверяется не только путем запуска, но и путем чтения, статических проверок и т.п.
Таблица 1 – Показатели эффективности различных методов тестирования
|
Методика |
Минимальная эффективность |
Средняя эффективность |
Максимальная эффективность |
|
Персональные просмотры проектных документов |
15% |
35% |
70% |
|
Неформальные групповые просмотры |
30% |
40% |
60% |
|
Формальные просмотры проектных документов |
35% |
55% |
75% |
|
Формальные инспекции кода |
30% |
60% |
70% |
|
Моделирование и прототипирование |
35% |
65% |
80% |
|
Проверка за партой |
20% |
40% |
60% |
|
Тестирование модулей |
10% |
25% |
50% |
|
Функциональное тестирование |
20% |
35% |
55% |
|
Комплексное тестирование |
25% |
45% |
60% |
|
Тестирование в реальных условиях |
35% |
50% |
65% |
|
Применение всех перечисленных методик тестирования |
93% |
99% |
99% |
Важно различать процессы тестирования и отладки. Отладка не является частным случаем тестирования. Процесс отладки направлен на установление точной природы известной ошибки, а затем на исправление этой ошибки. Эти два вида деятельности связаны, т.к. результаты тестирования являются исходными данными для отладки [10].
Успех отладки программы по большей части определяется рациональной организацией тестирования. В процессе отладки отыскиваются и устраняются, в основном, те ошибки, наличие которых устанавливается при тестировании. Тестирование не может доказать правильность - оно лишь может продемонстрировать наличие ошибок. Другими словами, нельзя гарантировать, что при помощи тестирования можно установить наличие всех ошибок. Поэтому в процессе отладки возникает две задачи:
- подготовить специальный набор тестов, чтобы обнаружить по возможности максимальное число ошибок. Однако чем дольше продолжается процесс тестирования (и отладки в целом), тем большей становится стоимость программы [17];
- правильно определить момент окончания отладки. Признаком возможности окончания отладки является полнота охвата, пропущенными через программу, тестами множества различных ситуаций, возникающих при выполнении возможных сценариев, и относительно редкое проявление ошибок на последнем отрезке процесса тестирования. Последнее определяется в соответствии с требуемой степенью надежности, указанной в спецификации его качества [10].
Отладка программы в любом случае предполагает обдумывание и логическое осмысление всей имеющейся информации об ошибке. Большинство ошибок можно обнаружить по косвенным признакам посредством тщательного анализа текстов программ и результатов тестирования без получения дополнительной информации. При этом используют различные методы:
- ручного тестирования;
- индукции;
- дедукции;
- обратного прослеживания.
Метод ручного тестирования. Это - самый простой и естественный способ данной группы. При обнаружении ошибки необходимо выполнить тестируемую программу вручную, используя тестовый набор, при работе с которым была обнаружена ошибка.
Метод очень эффективен, но не применим для больших программ, программ со сложными вычислениями и в тех случаях, когда ошибка связана с неверным представлением программиста о выполнении некоторых операций. Данный метод часто используют как составную часть других методов отладки [19].
Метод индукции основан на тщательном анализе симптомов ошибки, которые могут проявляться как неверные результаты вычислений или как сообщение об ошибке. Если компьютер просто «зависает», то фрагмент проявления ошибки вычисляют, исходя из последних полученных результатов и действий пользователя. Полученную таким образом информацию организуют и тщательно изучают, просматривая соответствующий фрагмент программы. В результате этих действий выдвигают гипотезы об ошибках, каждую из которых проверяют. Если гипотеза верна, то детализируют информацию об ошибке, иначе - выдвигают другую гипотезу [14].
Самый ответственный этап - выявление симптомов ошибки. Организуя данные об ошибке, целесообразно записать все, что известно о ее проявлениях, причем фиксируют, как ситуации, в которых фрагмент с ошибкой выполняется нормально, так и ситуации, в которых ошибка проявляется. Если в результате изучения данных никаких гипотез не появляется, то необходима дополнительная информация об ошибке. Дополнительную информацию можно получить, например, в результате выполнения схожих тестов [15].
В процессе доказательства пытаются выяснить, все ли проявления ошибки объясняет данная гипотеза, если не все, то либо гипотеза не верна, либо ошибок несколько.
Метод дедукции. По методу дедукции вначале формируют множество причин, которые могли бы вызвать данное проявление ошибки. Затем анализируя причины, исключают те, которые противоречат имеющимся данным. Если все причины исключены, то следует выполнить дополнительное тестирование исследуемого фрагмента. В противном случае наиболее вероятную гипотезу пытаются доказать. Если гипотеза объясняет полученные признаки ошибки, то ошибка найдена, иначе - проверяют следующую причину [12].
Метод обратного прослеживания. Для небольших программ эффективно применение метода обратного прослеживания. Начинают с точки вывода неправильного результата. Для этой точки строится гипотеза о значениях основных переменных, которые могли бы привести к получению имеющегося результата. Далее, исходя из этой гипотезы, делают предложения о значениях переменных в предыдущей точке. Процесс продолжают, пока не обнаружат причину ошибки [15].
Таким образом, в данной главе проведен теоретический обзор темы. Здесь рассмотрены основные этапы разработки программного обеспечения, а также дано определение терминам «тестирование» и «отладка», которые составляют основу работы.
2. ТЕСТИРОВАНИЕ
2.1. Виды тестирования
Принято выделять два основных вида тестирования:
- тестирование программы как черного ящика;
- тестирование программы как белого ящика [19].
Тестирование программы как черного ящика также называется тестированием с управлением по входу-выходу. В данном случае программа считается черным ящиком. Цель данного тестирования – выяснить обстоятельства, при которых поведение программы выходит за рамки ее спецификации [14].
Ключевым критерием в данном случае выступает исчерпывающее входное тестирование, которое достигается благодаря использованию всевозможных различных наборов входных данных.
В качестве примера может быть приведена задача определения возможности построения треугольника по заданным длинам трех сторон. Очевидно, что если эти числа будут вещественными, наборов входных данных для этой задачи будет бесконечное множество.
Таким образом, создать исчерпывающий тест для данной задачи невозможно по двум причинам:
- нельзя создать тест, который будет гарантировать отсутствие ошибок;
- разработка подобных тестов противоречит экономическим требованиям.
Получается, что в данной ситуации возможность исчерпывающего тестирования исключается. Следовательно, основная цель тестирования в этом случае – максимизировать количество ошибок, обнаруживаемых тестом. Для этого стоит отдельно рассматривать внутреннюю структуру программы [9].
Для исследования внутренней структуры используется стратегия белого ящика. В этом случае тестировщик получает наборы данных за счет анализа логики программного кода.
На первый взгляд может показаться, что в данном случае достаточно лишь построить набор тестов, где каждый оператор исполнялся хотя бы раз. Однако, программа может быть полностью проверена только в том случае, когда тесты покрывают выполнение кода по всем возможным маршрутам ее потока передач управления [11].
Важно понимать, что некоторые подмаршруты участвуют в других более крупных маршрутах. Пример графа передачи управления представлен на рисунке 2 [10].
Рисунок 2 – Граф передачи управления
Вершины данного графа соответствуют определенным линейным участкам программы, а дуги – передачам управления. Очевидно, программа содержит циклический оператор, который будет вызван 20 раз [11].
Для того, чтобы определить количество различных маршрутов, нужно посчитать число всевозможных путей из точки А в точку В. Данное количество определяется по формуле 1 [11]:
520 + 519 + … + 51 = 1014 (1)
В данном случае 5 – это количество различных путей внутри цикла. Таким образом, если на разработку одного теста в среднем тратится пять минут, то для построения полного набора тестов понадобится 5*1014 минут, что составляет примерно один миллиард лет.
Получается, что применение исчерпывающего тестирования маршрутов также является невозможным. Кроме того, данный вид тестирования не гарантирует выявления ошибки, зависящей от входных данных.
Реальный путь, применяющийся в тестировании большинства прикладных программ – совокупность обеих стратегий тестирования [19].
Понятие тестирования тесно связано с понятием отладки - исправлением ошибок в программном коде. Поэтому первый вопрос, на который должен ответить программист: в каком случае в программе есть ошибка? [11]
Важно понимать, что программа содержит ошибку в том случае, когда она ведет себя неразумно с точки зрения пользователя этой программы. Для этого важно предусмотреть следующие моменты:
- программа должна быть синтаксически корректна – в процессе трансляции не должны быть выявлены ошибки;
- программа должна правильно решать поставленную задачу – при вводе корректных данных программа должна выдавать правильный результат. Правильность результата при этом определяется заказчиком программы;
- программа не должна делать ничего лишнего;
- результат должен получаться за разумное время при разумных затратах прочих ресурсов;
- программа должна правильно реагировать на ввод некорректных данных, заранее предусматривая все исключительные ситуации [16].