Подход к обеспечению надежности №2 - Обнаружение и исправление ошибок в программе
ПО как объект тестирования имеет ряд особенностей:
отсутствие полностью определенного эталона (программы), которому должны соответствовать все результаты тестирования проверяемой программы;
высокая сложность программ и принципиальная невозможность построения тестовых наборов, достаточных для их исчерпывающей проверки;
невысокая степень формализации критериев качества процесса тестирования и достигаемого при этом качества объектов тестирования;
наличие в программах вычислительных и логических компонент, а также компонент, характеризующихся стохастическим и динамическим поведением.
Тестирование является основным методом обнаружения ошибок при отладке программ.При этом затраты на тестирование являются наибольшими, достигают 30 - 40% общих затрат на разработку программ и в значительной степени определяют качество созданного программного продукта. Высокая доля затрат на тестирование приводит к необходимости создания методов и средств, позволяющих достигать максимального качества программ при реальных ограничениях на длительность тестирования и на связанные с этим затраты. Создаются различные методы систематического и регламентированного тестирования, обеспечивающие наилучшее использование ресурсов проектирования с учетом особенностей создаваемых программ.
Для определения задач тестирования целесообразно выделить три стадии:
I. Тестирование для обнаружения ошибок в программе.
Основной целью тестирования для обнаружения ошибок является выявление всех отклонений результатов функционирования реальной программы от заданных эталонных значений. При этом задача состоит в обнаружении максимального числа ошибок, в качестве которых принимается любое отклонение от эталонов. На этой стадии успешным является тестирование, которое приводит к обнаружению ошибок. Если в результате тестирования ошибки не выявлены, то проведенные операции не дали сведений, позволяющих повысить качество программ и тем самым не оправдали затрат. Таким образом, эффективными являются операции тестирования, обладающие высокой способностью по обнаружению ошибок в программе. Чем больше ошибок выявляется на этой стадии при каждой операции тестирования, тем выше их эффективность и обоснованность затрат на их выполнение. С этих позиций тесты, не способствующие обнаружению ошибок и только подтверждающие корректность функционирования программ, являются неэффективными.
II. Тестирование для диагностики и локализации причин обнаруженных искажений результатов.
Применяется после тестирования для обнаружения ошибок. На этой стадии важнейшая задача - точно установить место искажения программы или данных, явившегося причиной отклонения результатов от эталонных при тестировании для обнаружения ошибок. Тем самым определяется часть программы, подлежащая корректировке. Эффективными являются тесты, способствующие быстрой и точной локализации первичных ошибок. На этой стадии затраты оправданы и тестирование можно считать успешным, если оно приводит к полной локализации ошибки, подлежащей исправлению.
III. Тестирование для контроля выполненных корректировок программ и данных (контрольное тестирование).
Контрольное тестирование применяется после локализации и устранения обнаруженных ошибок, его задача состоит в подтверждения правильности выполненной корректировки программы и в отсутствии проявления ранее обнаруженных ошибок. В этом случае успешность тестирования определяется отсутствием проявления ранее обнаруженной, локализованной и устраненной ошибки, а также отсутствием вторичных ошибок, которые могут появиться при корректировке.
Для тестирования применяются методы, предусматривающие упорядочение и систематизацию тестов по различным стратегиям и параметрам, и методы неупорядоченного тестирования. Основное внимание при упорядоченном тестировании сосредоточивается на обнаружении ошибок при исходных данных и условиях функционирования, заданных требованиями технического задания. Однако в реальных условиях на вход программы могут попадать сильно искаженные или ложные данные. Программы должны сохранять свою работоспособность при последующем поступлении данных, изменяющихся в заданных пределах. Для этого тестирование необходимо проводить не только при корректных исходных данных, но и при искаженных.
При неупорядоченном тестировании исходные данные, имитирующие внешнюю среду, случайным образом генерируются во всем диапазоне возможного изменения параметров, производится случайный перебор значений в произвольных сочетаниях различных величин. При этом многие значения исходных данных характеризуются малой вероятностью обнаружения ошибок и не оправдывают затраты на выполнение тестирования. Кроме того, возможно появление логически противоречивых данных. В то же время данные, наиболее важные с позиции реального использования программ и возможности обнаружения ошибок, могут оказаться не охваченными в процессе тестирования. При реально существующих ограничениях на объемы тестирования его неупорядоченное применение оказывается малоэффективным и почти не находит применения.
Стремление к рациональному использованию ограниченных ресурсов приводит к систематизации процесса и методов тестирования. Методы упорядоченного тестирования базируются на выделении факторов и параметров, позволяющих эффективно распределять ресурсы тестирования с учетом их влияния на качество программ. Систематизация может значительно изменяться в зависимости от этапов тестирования, однако можно выделить несколько общих принципов, на базе которых строятся основные методы тестирования. Для упорядочения операции тестирования используется информация о структуре программы и процессе обработки информации, о характере изменения и взаимосвязи переменных, о наиболее вероятных и важных сочетаниях исходных данных, о характеристиках ошибок и вероятности их проявления и т. д. В результате ограниченные ресурсы тестирования используются, прежде всего, для обнаружения наиболее опасных ошибок в наиболее важных режимах функционирования программ. С этой целью последовательно применяются методы тестирования: статический, детерминированный, стохастический и в реальном масштабе времени.
Статическое тестирование является наиболее формализованным и автоматизируемым методом проверки корректности программ. В качестве эталонов применяются правила структурного построения программных модулей и обработки данных, конкретизированные для проекта ПО в целом. Кроме того, могут использоваться некоторые частные правила обработки данных, зафиксированные в спецификациях на отдельные компоненты программ. Проверка степени выполнения этих правил проводится без исполнения объектного кода программы путем формального анализа текста программы на языке программирования. Операторы и операнды текста программ при этом анализируются в символьном виде, поэтому такой метод называют также символическим тестированием. Развитие и углубление символического тестирования может доводиться до уровня формальной верификации программы на соответствие ее текста детальной спецификации совокупности утверждений, полностью определяющей связи между входными и выходными данными этой программы.
Наиболее трудоемкими и детализирующими являются методы детерминированного тестирования. При детерминированном тестировании контролируется каждая комбинация исходных эталонных данных и соответствующая ей комбинация результатов функционирования программы. Это позволяет выявлять отклонение результатов от эталона с конкретным фиксированием всех значений исходных и результирующих данных, при которых это отклонение обнаружено.
Стохастическое тестирование применяется в случаях, когда невозможно перебрать все комбинации исходных данных и проконтролировать результаты функционирования программы на каждой из них (в сложных программах). При этом виде тестирования исходные тестовые данные задаются множествами случайных величин с соответствующими распределениями и для сравнения полученных результатов используются также распределения случайных величин. В результате при стохастическом тестировании возможно более широкое варьирование исходных данных, хотя отдельные ошибки могут быть не обнаружены, если они мало искажают средние статистические значения или распределения. Стохастическое тестирование применяется в основном для обнаружения ошибок, а для диагностики и локализации ошибок приходится переходить к детерминированному тестированию с использованием конкретных значений параметров из области изменения ранее использовавшихся случайных величин.
Последующее расширение области изменения исходных данных возможно при применении тестирования в реальном масштабе времени. В процессе такого тестирования проверяется исполнение программ и обработка исходных данных с учетом времени их поступления, длительности и приоритетности обработки, динамики использования памяти и взаимодействия с другими программами и т.д. При обнаружении отклонений результатов исполнения программ от предполагавшихся эталонных для локализации ошибки приходится фиксировать время и переходить к детерминированному тестированию.
Последним этапом функционального тестирования является оценка безошибочности программы, производимая на основе результатов тестирования как статистического эксперимента таким же методом, как оценка безотказности аппаратуры.
Отказы программ проявляются как случайные, однако носят детерминированный характер для заданного набора исходных данных (положение, аналогичное с любыми испытаниями по контролю качества объектов). При выборочном контроле качества некоторый объект выбирается случайно, но после того, как он был выбран, его качество детерминировано. Поэтому при стохастическом тестировании программ применимы математические методы выборочного контроля качества, если допустить, что проявление ошибки при одном тесте не зависит от проявления ошибки при другом тесте.
Поскольку обнаруженные ошибки в программе следует исправлять, оценку надежности программы при стохастическом функциональном тестировании целесообразно производить на основании заключительной серии стохастических тестов, когда отказы программы отсутствуют. Тогда для оценки вероятности безотказной работы программы может быть использована формула:
,
где рн - нижняя доверительная граница вероятности безотказной работы программа при однократном прохождении;
gн - доверительная вероятность (>=0,9, как правило);
n - количество прохождений программы при тестировании.
Сделанное допущение относительно независимости результатов отдельных стохастических тестов программы не вполне обосновано, так как наличие ошибки в программе обнаруживается, вероятно, большим количеством тестов, чем это можно ожидать, исходя из независимости их результатов. Поэтому представляет интерес другой подход, когда программа рассматривается как сообщение, состоящее из N символов. Пусть каждый стохастический тест проверяет в среднем r символов из N и пусть один из N элементов содержит ошибку.
Тогда вероятность того, что при одном тесте ошибка не будет обнаружена, оценивается как 1-r/N. Вероятность того, что при n независимых тестах ошибка не будет обнаружена, равна (1-r/N)n. Если ошибочных символов в программе больше, чем один, то вероятность их обнаружения одним тестом будет еще больше, так что оценка является оценкой сверху.