- •Качество и надежность программного обеспечения
- •Лекция 1. Введение. Основные стандарты и термины по качеству программного обеспечения. Метрики и критерии качества программных продуктов. Составляющие качества программных продуктов.
- •Общие термины
- •Лекция 2. Классификация видов сложности программных продуктов. Метрические характеристики программ по м.Холстеду
- •Оценивание качества разработки программ на основе метрик Холстеда. Измеримые свойства алгоритмов
- •Длина программы
- •4. Объем программы
- •Потенциальный объем V*
- •Лекция 3. Уровень программ. Интеллектуальное содержание программы.
- •1. Уровень программы
- •2. Вывод уравнения уровня программы
- •3. Определение интеллектуального содержания программ
- •Лекция 4. Работа в программировании. Уровни языков программирования. Метрика числа ошибок в программе.
- •5 S 20 в сек
- •Значение уровня языка
- •Лекция 5. Метрики структурной сложности программ.
- •Где pi – количество вершин ветвления в I-том маршруте без учета последней вершины
- •M5 1 – 3 – 4 – 6 – 8 – 14 независимые
- •Лекция 6. Методы и средства измерения характеристик программ. Аппаратные измерительные мониторы.
- •Лекция 7. Программные измерительные мониторы.
- •Лекция 8. Понятие корректности программ.
- •II. Эталоны и методы проверки корректности.
- •Лекция 9. Аналитическая проверка корректности программ. Верификация программ.
- •Invk (x1, … , xn),
- •Invt1 (x1, … , xn): p ; invt2 (x1, … , xn): q ; invt3 (x1, … , xn) ; … ,
- •U: invr(x1, … , xn) u0
- •Лекция 10. Тестирование программных продуктов
- •1. Основные понятия процесса тестирования
- •2. Объекты тестирования
- •3. Категории тестов для различных объектов тестирования
- •Лекция 11. Виды, критерии и методы тестирования. Методы структурного тестирования программ
- •1. Тестирование на основе потока управления
- •2. Тестирование на основе потока данных
- •Лекция 12. Методы функционального тестирование программных продуктов
- •1. Метод эквивалентного разбиения
- •1.1. Выделение классов эквивалентности
- •1.2. Построение теста
- •2. Анализ граничных значений
- •3. Метод функциональных диаграмм
- •4. Метод, основанный на предположении об ошибке
- •Лекция 13. Основные показатели надежности программного обеспечения (по). Математические модели оценки надежности по.
- •13.1. Основные показатели надежности программного обеспечения (по).
- •13.2. Математические модели оценки надежности по.
- •Модель Джелинского-Моранды.
- •Модель Шика-Уолвертона.
- •Лекция 14. Модели, основанные на методе "посева" и разметки ошибок, и модели на основе учета структуры входных данных
- •Модель Нельсона. Применение последовательного анализа Вальда для снижения количества прогонов программы.
- •Лекция 15. Методы повышения надежности программ и оценка эффективности их применения.
- •15.1 Влияние избыточности на повышение надежности программ
- •Эффективность применения избыточности для повышения надежности комплексов программ
- •Влияние оперативного контроля и восстановления на производительность эвм.
- •Методы программного восстановления
- •Методы обеспечения надежности комплексов программ при сопровождении
- •Литература
II. Эталоны и методы проверки корректности.
Эталоны для проверки корректности программ могут использоваться в следующих трех формах, поясняемых с помощью рис.13:
1. Формализованные правила.
2. Программные спецификации.
3. Тесты.
Формализованные правила - имеют достаточно неопределенностей, так как опреде-ляются двумя видами требований
требования стандартов (общероссийских и стандартов предприятий)
требования языков и технологий программирования.
синтаксический
контроль семантический
контроль структурный
контроль.
контроль
полноты спецификаций верификация
программ.
Статическое
и динамическое тестирование
Рис.13
Для полной убедительности в корректности программ одних формализованных правил недостаточно.
2. Программные спецификации - относятся к функциональным эталонам и в основ-ном обеспечивают проверку корректности программ в статике.
3. Тесты.
В зависимости от стадии и характера проверки разделяются тесты делятся на статические и динамические. Статическое тестирование - ручное тестирование программ, начиная со стадии формирования требований к программе. На стадии кодирования при статическом тестировании некоторую часть маршрутов исполнения тестируют вручную. Динамическое тестирование подразумевает достаточно полную структурную и функциональную проверку выполнения программы.
Как формируются эталоны для тестирования? Существует несколько способов формирования эталонов:
Использование аналитических выражений. Этот способ особенно подходит при детерминированном тестировании, так как имеется возможность сравнить результаты тестирования с ожидаемыми результатами. Имеются ограничения в использовании этого метода, если неизвестны или отсутствуют аналитические выражения связывающие входные данные и результаты; иногда требуется использовать много допущений.
Использование моделирования на ЭВМ. Способ является универсальным. При этом ряд данных моделируется другим способом и по другим алгоритмам, нежели испытываемая программа и на других ЭВМ. Причем наборы входных данных создаются по случайным законам, что обеспечивает высокую гибкость этого способа.
Использование результатов испытаний предшествующих вариантов программ.
При этом используется ранее накопленный опыт испытателя или других исследователей, выраженный в экспертных оценках ожидаемых результатов.
Степень достоверности проверки корректности программ при использовании этих методов убывает по номерам способов формирования эталонов.
В 1-ом случае обеспечивается 100% гарантия корректности программ, в третьем случае такой уверенности нет, но мы можем убедиться в том, что программа работает так же или иначе, чем аналогичный вариант. Менее достоверные тесты приходится использовать из-за недостаточности сил и средств.
Лекция 9. Аналитическая проверка корректности программ. Верификация программ.
Корректность является статическим свойством программы, поскольку она не зависит от времени (если, конечно, не изменяются цели разработки) и отражает специфику ошибок разработки программ (ошибок проекта и кодирования).
Различают два типа проверки корректности:
валидация (validation) – установление соответствия между тем, что делает программа, и тем, что нужно Заказчику;
верификация (verification) – установление соответствия между программой и ее спецификацией.
Определение верификациии симметрично ввиду относительного характера свойства корректности: если программа не соответствует своей спецификации, то либо программа, либо спецификация, либо оба этих объекта содержат ошибки. Перефразируя известное изречение Э.Дейкстры о тестировании программ, можно сказать, что верификация способна доказать отсутствие ошибок в программе, но не всегда доказывает их присутствие.
В отличие от тестирования верификация предполагает аналитическое исследование свойств программы по ее тексту (без выполнения программы). Таким образом, для проведения верификации необходимо построить формально-логическую систему, в которой были бы формально определены свойства корректности программы. Для этих целей наиболее широкое применение получило исчисление предикатов первого порядка, расширенное аксиоматической арифметикой.
Можно сказать, что верификация – это вычисление истинности предиката от двух аргументов: программы и спецификации. Истинность этого предиката устанавливает свойство корректности программы, если спецификация не содержит ошибок, однако, его ложность, вообще говоря, не означает наличие ошибок в программе, а требует более точного разбора.
Учитывая специфику проявления ошибок в программах в процессе их выполнения на ЭВМ, целесообразно выделить в понятие корректности программы два свойства:
частичную корректность – удовлетворение внешним (входной и выходной) спецификациям программы при условии завершения выполнения программы;
завершенность – достижение в процессе выполнения выхода программы при определенных входной спецификацией данных.
Свойство завершенности не является тривиальным для такого объекта, как программа, ввиду возможности циклических и рекурсивных вычислений, а также наличия частично-определенных операций. Случаи, когда свойство завершенности не удовлетворяется, довольно обычны для программ с ошибками, и приводят к заведомо некорректным программам независимо от спецификации выхода.
Каждое из двух выделенных свойств корректности программы может удовлетворяться или не удовлетворяться. Таким образом, можно выделить шесть основных задач анализа корректности программы:
частичная корректность (при условии завершенности);
завершенность программы;
незавершенность программы;
тотальная корректность (частичная корректность и завершенность);
частичная некорректность (некорректность при условии завершенности);
некорректность (незавершенность или частичная некорректность).
Разделение свойств частичной корректности и завершенности следует рассматривать как методологический прием, направленный на уменьшение сложности верификации программ.
Рассмотрим формальные постановки задач анализа корректности.
Введем ограничение: будем рассматривать программы, начинающиеся оператором START (первый выполняемый оператор) и заканчивающиеся оператором STOP (последний выполняемый оператор).
Спецификацию программы Prgm будем определять путем приписывания индуктивных утверждений точкам разреза графа потоков управления программы (точкам между операторами программы). При этом выходу оператора START приписывается входной предикат (предусловие) программы P(x), определяющий множество допустимых значений исходных данных x (x допустимо, если P(x): true), а входу оператора STOP приписывается выходной предикат (постусловие) Q(x,y), определяющий целевую функцию программы (связь между входными и выходными данными программы).
Тогда свойство частичной корректности программы определяется следующей формулой логики предикатов:
PCOR(Prgm, P, Q): x ( P(x) fin(x) Q( x, f(x) ) ),
где fin(x) – предикат завершения программы Prgm, начатой в состоянии x;
f(x) – функция, вычисляемая программой Prgm,
свойство завершенности может быть определено формулой:
FIN(Prgm, P): x ( P(x) fin(x) ),
а свойство тотальной корректности формально выражается как одновременное присутствие свойств частичной корректности и завершенности:
TCOR(Prgm, P, Q): x ( P(x) Q(x, f(x) ) fin(x) ).
Аналогичным образом могут быть формализованы и другие перечисленные выше свойства корректности (записать самостоятельно).
Заметим, что для произвольных программ каждое из этих свойств (завершенность и частичная корректность) является алгоритмически неразрешимым, т.е. не существует алгоритма, позволяющего оценить истинность соответствующих формул логики предикатов. Однако для отдельных классов программ в настоящее время разработаны достаточно эффективные методы верификации, позволяющие вручную или автоматически проводить соответствующие доказательства. Такие методы могут рассматриваться как составная часть процессов разработки и отладки программ, обеспечивая логическую завершенность этих процессов.
Наиболее распространенным методом доказательства частичной корректности программ является метод индуктивных утверждений, предложенный Флойдом. Он позволяет свести доказательство частичной корректности программы к доказательству некоторого конечного числа утверждений, записанных на языке исчислений предикатов первого порядка и имеющих интерпретацию в соответствующей проблемной области.
Рассмотрим метод индуктивных утверждений для программ с конечным множеством простых переменных { x1, x2, … xn }, где n1, а операторами являются:
операторы присваивания вида xi := f (x1, x2, … xn);
составной оператор вида A ; B ;
оператор условного перехода if (x1, x2, … xn) then L+ else L– ,
где L+, L– – метки операторов, которым передается управление;
начальный оператор START;
конечный оператор STOP.
Такой состав структурных компонентов вполне достаточен для представления произвольного алгоритма и поэтому не ограничивает общности излагаемого метода.
Установление частичной корректности осуществляется за четыре последовательных шага.
Шаг 1. Разрезание циклов программы
Очевидно, что при выполнении программы для различных исходных данных возможны различные последовательности операторов, начинающиеся оператором START и оканчивающиеся оператором STOP. Назовем такие последовательности трассами вычислений.
Сложность анализа частичной корректности программы разбиением на трассы заключается в том, что при наличии циклов в программе он не может быть выполнен непосредственным перебором всех трасс. Эта сложность может быть преодолена путем включения в граф потока управления программы конечного числа точек, называемых точками разреза, таким образом, что каждый цикл содержит одну такую точку, которая “разрезает” циклические пути на два:
путь через тело цикла;
путь к выходу из цикла.
Шаг 2. Получение аннотированной программы
С каждой точкой разреза k свяжем предикат