Технологии программирования
Сущность и актуальность дисциплины. Качество программного обеспечения. Требования стандарта к организации системы качества. Спецификация и проектирование программного обеспечения при структурном подходе. Основные подходы в формировании тестовых наборов.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | лекция |
Язык | русский |
Дата добавления | 25.12.2014 |
Размер файла | 1,9 M |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Вариант использования - некоторая очевидная для действующего лица процедура, решающая его конкретную задачу. Все варианты использования, так или иначе, связаны с требованиями к функциональности разрабатываемой системы и могут сильно отличаться по объему выполняемой работы.
Связь - взаимодействие действующих лиц и соответствующих вариантов использования.
Варианты использования также могут быть связаны между собой. При этом фиксируют связи использования и расширения.
Использование подразумевает, что существует некоторый фрагмент поведения разрабатываемого программного обеспечения, который повторяется в нескольких вариантах использования. Этот фрагмент оформляют, как отдельный вариант использования и указывают связь с ним типа «использование».
Расширение применяют, если имеется два подобных варианта использования, различающиеся наличием в одном из них некоторых дополнительных действий. В этом случае дополнительные действия определяют как отдельный вариант использования, который связан с основным вариантом связью типа «расширение».
Рис. 13.3. Основные условные обозначения диаграмм вариантов использования: а - действующее лицо; б - вариант использования; в - связь
Построение концептуальной модели предметной области
Концептуальные модели в соответствии с определением оперируют понятиями предметной области, атрибутами этих понятий и отношениями между ними. Понятию в предметной области разрабатываемого программного обеспечения могут соответствовать как материальные предметы, так и абстракции, которые применяют специалисты предметной области.
Основным понятиям в модели ставятся в соответствие классы. Класс при этом традиционно понимают как совокупность общих признаков заданной группы объектов предметной области. В соответствии с этим определением на диаграмме классов каждому классу соответствует группа объектов, общие признаки которых и фиксирует класс.
Рис. 13.6. Обозначение класса на концептуальной диаграмме классов: а - без уточнения характеристик; б - с уточнением атрибутов
В качестве атрибутов представляют некоторые, существенные с точки зрения решаемой задачи характеристики объектов, например идентифицирующие значения (имя, номер). Для конкретного объекта атрибут всегда имеет определенное значение. На диаграмме классов атрибуты обычно показывают в секции атрибутов.Под отношением классов понимают статическую, т. е. не зависящую от времени, связь между классами. Различают два основных вида отношений: ассоциация и обобщение.
Отношение ассоциации означает наличие связи между экземплярами классов или объектами.
Обобщением называют такое отношение между классами, при котором любой объект одного класса (подтипа) обязательно является также и объектом другого класса, называемого в данном контексте супертипом.
На практике определение основных понятий предметной области, которые должны представляться на контекстной диаграмме в виде классов, является не тривиальной задачей. Обычно используют следующий способ: формируют множество понятий-кандидатов из существительных, характеризующих предметную область в описании вариантов использования; исключают понятия, не существенные для данного варианта использования.
Диаграмма последовательностей системы. Системные события и операции
Диаграмма последовательностей системы -- графическая модель, которая для определенного сценария варианта использования показывает генерируемые действующими лицами события и их порядок. При этом система рассматривается как единое целое. Для построения диаграммы последовательностей системы необходимо: представить систему как «черный ящик» и изобразить для нее линию жизни - вертикальную пунктирную линию, подходящую к блоку снизу; идентифицировать каждое действующее лицо и изобразить для него линию жизни (много действующих лиц бывает в вариантах совместного использования программного обеспечения); из описания варианта использования определить множество системных событий и их последовательность; изобразить системные события в виде линий со стрелкой на конце между линиями жизни действующих лиц и системы, а также указать имена событий и списки передаваемых значений.
Системные события и операции
События, которые генерируются для системы действующими лицами, называют системными. Системные события инициируют выполнение соответствующего множества операций, также называемых системными, называя по имени соответствующего сообщения. // Множество всех системных операций определяют, идентифицируя системные события всех вариантов использования. Обычно описание системной операции содержит: имя операции и ее параметры; описание обязанности; указание типа; названия вариантов использования, в которых она используется; примечания для разработчиков алгоритмов и т. д.; описание обработки возможных исключений; описание вывода неинтерфейсных сообщений; предположение о состоянии системы до выполнения операции (предусловие); описание изменения состояния системы после выполнения операции (постусловие).
Диаграммы деятельностей
В зависимости от степени детализации диаграммы деятельностей так же, как диаграммы классов, используют на разных этапах разработки. На этапе анализа требований и уточнения спецификаций диаграммы деятельностей позволяют конкретизировать основные функции разрабатываемого программного обеспечения.
Под деятельностью в данном случае понимают задачу (операцию), которую необходимо выполнить вручную или с помощью средств автоматизации. Каждому варианту использования соответствует своя последовательность задач. В теоретическом плане диаграммы деятельности являются обобщенным представлением алгоритма, реализующего анализируемый вариант использования. На диаграмме деятельность обозначается прямоугольником с закругленными углами (рис. 13.12, а).
Диаграммы деятельностей позволяют описывать альтернативные и параллельные процессы. Для обозначения альтернативных процессов используют ромб (рис. 13.12, б), условие указывают над ним слева или справа, а альтернативы «да», «нет» - рядом с соответствующими выходами. С помощью этого же блока можно построить циклический процесс. Множественность активации деятельности обозначают символом «*», помещенным рядом со стрелкой активации деятельности, и при необходимости уточняют надписью вида «для каждой строки».
Рис 13.12. Условные обозначения диаграммы деятельностей: а - деятельность; б - выбор; в - линейки синхронизации; г - начало, д - конец
Рис. 13.13. Пример диаграммы деятельности с указанием параллельности процессов
Проектирование программного обеспечения при объектном подходе
Основной задачей логического проектирования при объектном подходе является разработка классов для реализации объектов, полученных при объектной декомпозиции, что предполагает полное описание полей и методов каждого класса.
Физическое проектирование при объектном подходе включает объединение классов и других программных ресурсов в программные компоненты, а также размещение этих компонентов на конкретных вычислительных устройствах.
Разработка структуры программного обеспечения при объектном подходе
Большинство классов можно отнести к определенному типу, который применительно к данному подходу называют стереотипам, например: классы-сущности (классы предметной области); граничные (интерфейсные) классы; управляющие классы; исключения и т. д. (рис. 14.1).
Рис. 14.1. Условные обозначения стереотипов классов: а - класс-сущность; б - граничный класс; в - управляющий класс; г - явное указание стереотипа
Граничные классы обеспечивают взаимодействие между действующими лицами и внутренними элементами системы. К этому типу относят как классы, реализующие пользовательские интерфейсы, так и классы, обеспечивающие интерфейс с аппаратными средствами или программными системами. Для обнаружения граничных классов изучают пары «действующее лицо - вариант использования».
Управляющие классы служат для моделирования последовательного поведения, заложенного в один или несколько вариантов использования.
Если количество классов-кандидатов и других ресурсов велико, то их целесообразно объединить в группы - пакеты. Пакетом при объектном подходе называют совокупность описаний классов и других программных ресурсов, в том числе и самих пакетов. Объединение в пакеты используют только для удобства создания больших проектов, количество классов в которых велико. При этом в один пакет обычно собирают классы и другие ресурсы единого назначения.
Диаграмма пакетов показывает, из каких частей состоит проектируемая программная система, и как эти части связаны друг с другом.
Связь между пакетами фиксируют, если изменения в одном пакете могут повлечь за собой изменения в другом. Она определяется внешними связями классов и других ресурсов, объединенных в пакет. Возможны различные виды зависимости классов, например: объекты одного класса посылают сообщения объектам другого класса; объекты одного класса обращаются к компонентам объектов другого; объекты одного класса используют объекты другого в списке параметров методов и т. п.
Самыми хорошими технологическими характеристиками отличается вариант, при котором каждый пакет включает интерфейс, содержащий описание всех ресурсов данного пакета, и взаимодействие пакетов осуществляется только через этот интерфейс. Изменения реализации ресурсов пакета в этом случае не затрагивает других пакетов. И только изменения в интерфейсе могут потребовать изменения пакетов, использующих ресурсы данного пакета.
Пакеты, с которыми связаны все пакеты программной системы, называют глобальными.
Рис. 14.2. Условные обозначения, применяемые на диаграммах пакетов: а - пакт; б - пакет с обозначением содержимого; в - глобальный пакет; г - зависимость классов (стрелка указывает направление вызовов)
Определение отношений между объектами.
После определения основных пакетов разрабатываемого программного обеспечения переходят к детальному проектированию классов, входящих в каждый пакет. Классы-кандидаты, которые предположительно должны войти в конкретный пакет; показывают на диаграмме классов этапа проектирования и уточняют отношения между объектами указанных классов.
Пример 14.2. Определить классы-кандидаты пакета Объекты задачи.
Выполним анализ концептуальной модели предметной области (рис. 14.9), описания основного варианта использования Решение задачи и его диаграммы деятельностей (см. рис. 14.4).
Список классов-кандидатов, полученный на основе данного анализа, выглядит следующим образом:
класс Задание - объекты данного класса должны создаваться каждый раз, когда пользователь инициирует новое задание;
семейство классов с базовым классом Алгоритм -- объекты данного класса должны создаваться, когда определен алгоритм решения задачи;
класс Данные -- объекты данного класса должны создаваться при определении (вводе или выборе из базы) данных;
класс Результаты -- объекты данного класса должны создаваться при решении конкретной задачи конкретным алгоритмом с использованием конкретных данных.
Исходный вариант диаграммы классов пакета Объекты задачи показан на рис. 14.5.
Рис 14.5. Исходная диаграмма классов пакета Объекты задачи
Основой для проектирования классов является уточнение взаимодействия объектов этих классов в процессе реализации вариантов использования. При этом применяют диаграммы последовательностей и диаграммы кооперации. Если же необходимо описать взаимодействие объектов при обработке конкретного сообщения, удобны именно диаграммы последовательностей.
Диаграммы последовательностей этапа проектирования.
Диаграммы последовательностей этапа проектирования
Диаграммы последовательностей этапа проектирования отображают взаимодействие объектов, упорядоченное по времени. В отличие от диаграмм последовательности этапа анализа на ней показывают внутренние объекты, а также последовательность сообщений, которыми обмениваются объекты в процессе реализации фрагмента варианта использования, называемого сценарием.
Объекты изображают в виде прямоугольников, внутри которого указана информация, идентифицирующая объект: имя, имя объекта и имя класса или только имя класса (рис. 14.6).
Каждое сообщение представляют в виде лилии со стрелкой, соединяющей линии жизни двух объектов. Эта линии помещают на диаграмму в порядке генерации сообщений (сверху вниз и слева направо). Сообщению присваивают имя, но можно указать и аргументы, и управляющую информацию, например, условие формирования или маркер итерации (*). Возврат при передаче синхронных сообщений подразумевают по умолчанию.
Рис 14.6. Условные обозначения объектов в UML: а - объект. б - объект с уточнением класса; в - непоименованный объект указанного класса
Если объект создается сообщением, то его рисуют справа от стрелки сообщения так, чтобы стрелка сообщения входила в него слева.
Диаграммы последовательностей также позволяют изображать параллельные процессы. Асинхронные сообщения, которые не блокируют работу вызывающею объекта, показывают половинкой стрелки (рис. 14.7, а). Такие сообщения могут
создавать новую ветвь процесса;
создавать новый объект (рис. 14.7,6);
устанавливать связь с уже выполняющейся ветвью процесса.
На линии жизни в этом случае дополнительно показывают активации, которые обозначаются прямоугольником, наложенным поверх линии жизни (рис. 14.7, в).
Уничтожение объекта показывают большим знаком «X» (рис. 14.7, г).
При необходимости линию жизни можно прервать, чтобы не уточнять обработку, не связанную с анализируемыми объектами (рис. 14.7, д).
Рис. 14.7. Условные обозначения асинхронных передач управления: а - асинхронное сообщение, б - создание объекта (не обязательно асинхронное); в - вшивании объекта; г - уничтожение объекта; д - разрыв (выполнение прочей обработки)
Диаграммы кооперации.
Диаграмма кооперации - это альтернативный способ представления взаимодействия объектов в процессе реализации сценария, который позволяет по-другому взглянуть на ту же информацию. В отличие от диаграмм последовательностей диаграммы кооперации показывают потоки данных между объектами классов, что позволяет уточнить связи между ними.
Пример 14.4. Разработать диаграмму кооперации для сценария Процесс решения. Изобразим на Одной диаграмме три возможных случая реализации сценария, нумеруя сообщения в порядке их возможной генерации (рис. 14.10).
Рис 14.10. Диаграмма кооперации сценария Процесс решения
Такое представление позволяет описать потоки данных, передаваемых между объектами классов Решение, Задание и Алгоритм, реализующий метод, для сценария Процесс решения.
Уточнение отношений классов.
Процесс проектирования классов начинают с уточнения отношений между ними. Па этапе проектирования помимо ассоциации и обобщения различают еще два типа отношения между классами: агрегацию и композицию.
К сожалению, до настоящего времени не существует единой устоявшейся терминологии объектно-ориентированного проектирования. В табл. 14.1 приведены соответствия между основными терминами, используемыми наиболее известными авторами в этой области.
Агрегацией называют ассоциацию между целым и его частью или частями. Агрегацию вместо ассоциации указывают, если отношение «целое-часть» в конкретном случае существенно. Например, если колесо нас интересует только как часть автомобиля, то между соответствующими классами целесообразно указать отношение агрегации, а если колесо - товар, также как и автомобиль, то связь целое-часть не существенна.
Композиция - более сильная разновидность агрегации, которая подразумевает, что объект-часть может принадлежать только единственному целому. Объект-часть при этом создается и уничтожается только вместе со своим целым.
Уточненные отношения между классами фиксируют на диаграмме классов. Для этого используют специальные уловные обозначения (рис. 14.11).
Рис. 14.11. Условные обозначения специальных видов ассоциации: а -- композиция; б - агрегация
Поскольку отношение ассоциации и его подвиды (агрегация и композиция) означают наличие обмена сообщениями между объектами классов целесообразно уточнить направление передачи сообщений. Навигацию (направление ассоциации) показывают стрелкой на конце линии ассоциации. Если стрелки указаны с обеих сторон, то это означает двунаправленную ассоциацию.
Таблица 14.1
Нотация |
Термины |
||||
UML |
Класс |
Ассоциация |
Обобщение |
Агрегация |
|
Буч |
Класс |
Использование |
Наследование |
Включение |
|
Коад |
Класс, объект |
Связь экземпляров |
Обобщение-специализация |
Часть-целое |
|
Якобсон |
Объект родства |
Ассоциация |
Наследование |
Состоит из |
|
Оделл |
Тип объекта |
Связь |
Подтип |
Композиция |
|
Рамбо |
Класс |
Ассоциация |
Обобщение |
Агрегация |
|
Шлеер/Меллор |
Объект |
Связь |
Подтип |
Не определена |
Специальное обозначение на диаграмме классов этапа проектирования используют для указания абстрактных классов и методов: на диаграмме классов их имена выделяют курсивом, либо перед именем класса указывают стереотип «abstract».
UML также включает специальную нотацию для обозначения параметризованных классов или шаблонов (рис. 14.12, а). Получение из такого класса, класса с конкретными типами элементов называют связыванием. Связывание можно обозначить двумя способами: явно указав тип параметра (рис. 14.12, б) и используя условное обозначение уточнения (рис. 14.12, в).
Рис. 14.12. Условное обозначение параметризованного класса: а - параметризованный класс, б - явное указания типа параметра при связывании; в - использование уточнения
Диаграммы классов позволяют также отобразить ограничения, которые невозможно показать, используя только понятия, рассмотренные выше (ассоциации, обобщения, атрибуты, операции). Например, показать, что средний балл студентов должен определяться по соответствующей формуле. Подобную, информацию на диаграмме классов можно представить в виде записи на естественном языке или в виде математической формулы, поместив их" в фигурные скобки.
Особое место в процессе проектирования классов занимает проектирование интерфейсов.
Интерфейсы в UML.
Интерфейсы
Интерфейсом в UML называют класс, содержащий только объявление операций. Отдельное описание интерфейсов улучшает технологические качества проектируемого программного обеспечения. Интерфейсы широко применяют при разработке сетевого программного обеспечения, которое должно идентично функционировать в гетерогенных средах, а также для организации взаимодействия с системами управления базами данных и т. п., так как механизм полиморфного наследования позволяет создавать различные реализации одного и того же интерфейса.
С точки зрения теории объектно-ориентированного программирования интерфейс представляет собой особый вид абстрактного класса, отличающийся тем, что он не содержит методов, реализующих указанные операции, и объявлений полей. Другими словами, абстрактные классы позволяют определить реализацию некоторых методов, а интерфейсы требуют отложить определение всех методов.
На диаграмме классов интерфейс можно показать двумя способами: с помощью специального условного обозначения (рис. 14.13, а) или, объявив для класса стереотип «Interface» (рис. 14.13, б).
Реализацию интерфейса также можно показать двумя способами: сокращенно (рис. 14.14, а) или, используя отношение реализации (рис. 14.14, б).
Для остальных классов, ассоциированных с интерфейсом, следует уточнить ассоциацию, показав отношение зависимости. Это отношение в данном случае означает, что класс использует указанный интерфейс (рис. 14.15), т. е. обращается к описанным в интерфейсе функциям.
Рис. 14.13. Условные обозначения интерфейса в UML: а -- специальное обозначение; б - с указанием стереотипа
Рис 14.14. Условные обозначения реализации интерфейсов: а - сжатая форма; б - с указанием отношения реализации
Одновременно с уточнением отношений классов в пакете следует продумать и отношения классов, включенных в различные пакеты, между собой.
Рис. 14.15. Обозначение зависимости класса от интерфейса
Проектирование классов.
Собственно проектирование классов предполагает окончательное определение структуры и поведения его объектов. Структура объектов определяется совокупностью атрибутов и операций класса. Каждый атрибут - это поле или совокупность полей данных, содержащихся в объекте класса.
Поведение объектов класса определяется реализуемыми обязанностями. Обязанности выполняются посредством операций класса.
Таким образом, при проектировании класса, помимо имени и максимально полного списка атрибутов, необходимо уточнить его ответственность и операции. Причем как атрибуты, так и операции в процессе проектирования целесообразно дополнительно специфицировать. В зависимости от степени детализации диаграммы классов обозначение атрибута может, помимо имени, включать: тип, описание видимости и значение по умолчанию. Для этого используют следующий формат:
<признак видимости> <имя>:<тип> = <значение по умолчанию>,
где признак видимости может принимать одно из трех значений: «+» - общий; «#» - защищенный; «-» - скрытый.
Как упоминалось выше, операциями называют основные действия, реализуемые классом. В отличие от методов, операции не всегда реализуются классом непосредственно. Например, операция Ввод числа может быть реализована агрегированным интерфейсным элементом «окно ввода».
Полное описание операции на диаграмме класса в UML может выглядеть следующим образом:
<признак видимости><имя>(<список параметров>):
< тип возвращаемого значения>.
Ответственностью класса называют кратное неформальное перечисление основных функций объектов класса. Ответственность класса обычно определяют на начальных этапах проектирования, когда атрибуты и операции класса еще не определены. Эту информацию отображают на диаграмме классов в специальных секциях условного изображения класса (рис. 14.17).
Имя класса |
|
Атрибуты |
|
Операции() |
|
Ответственность |
Рис. 14.17. Полное условное обозначение класса в UML
Проектирование методов класса.
Достаточно существенную информацию о действиях, которые должны, выполняться методами класса, можно получить, анализируя диаграммы последовательности действий. Однако алгоритмы всех сколько-нибудь сложных методов необходимо проработать детально. При этом можно использовать как уже известные нотации (схемы алгоритмов и псевдокоды), так и диаграммы деятельностей.
Диаграммы деятельностей, которые предлагалось использовать в процессе уточнения спецификаций для описания вариантов использования, могут использоваться и при проектировании методов обработки сообщений, в том числе и затрагивающих несколько объектов. В последнем случае целесообразно указать вертикальными пунктирными линиями ответственности объектов соответствующих классов, что позволит проследить вызовы других объектов.
Следует помнить, что в соответствии с общими правилами процедурной декомпозиции любую деятельность можно декомпозировать и изобразить в виде диаграммы деятельности более низкого уровня.
Пример 14.8. Построить диаграмму деятельности для операции Начать () класса Решение. Анализ рис. 14.4, 14.7 - 14.8 показывает, что данная деятельность затрагивает три объекта уже детализированных классов Решение, Алгоритм и Задание. Определим зоны ответственности объектов этих классов (рис.14.21):
Рис. 14.21. Диаграмма деятельности для операции Решение Начать()
объект класса Решения организует обработку, т. е. инициализирует переменные (в том числе определяет тип Алгоритма), создает объект класса Алгоритм требуемого типа, активизируют обработку, а затем уничтожает объект класса Алгоритм;
объект класса Задание должен в ответ на запрос сообщить тип Алгоритма, предоставить данные и запомнить результаты;
объект класса Алгоритм отвечает за решение задачи.
Полностью спроектированные классы реализуют на конкретном языке программирования.
Компоновка программных компонентов.
Диаграммы компонентов применяют при проектировании физической структуры разрабатываемо программного обеспечения. Эти диаграммы показывают, как выглядит программное обеспечение на физическом уровне, т. е. из каких частей оно состоит и как эти части связаны между собой.
Диаграммы компонентов оперируют понятиями компонент и зависимость. Под компонентами при этом понимают физические заменяемые части программного обеспечения, которые соответствуют некоторому набору интерфейсов и обеспечивают их реализацию. По сути дела, это отдельные файлы различных типов: исполняемые (.ехе), текстовые, графические, таблицы баз данных и т. п., составляющие разрабатываемое программное обеспечение. Условные графические обозначения компонентов различных типов приведены на рис. 14.22.
Рис. 14.22. Условные обозначения компонентов в UML: а - программный компонент; б - файл; в - база данных; г - таблица базы данных
Зависимость между компонентами фиксируют, если один компонент содержит некоторый ресурс (модуль, объект, класс и т. д.), а другой - его использует. Качество компоновки оценивают по количеству и типу связей между компонентами, т. е. по степени независимости компонентов. На диаграмме компонентов зависимость обозначают пунктиром со стрелкой на конце.
На рис. 14.23 в качестве примера приведена диаграмма компонентов системы решения комбинаторно-оптимизационных задач.
Рис. 14.23. Диаграммы компонентов системы решения комбинаторно-оптимизационных задач
Проектирование размещения программных компонентов для распределенных программных систем.
При физическом проектировании распределенных программных систем необходимо определить наиболее оптимальный вариант размещения программных компонентов на реальном оборудовании в локальной или глобальной сетях. Для этого используют специальную модель UML - диаграмму размещения.
Диаграмма размещения отражает физические взаимосвязи между программными и аппаратными компонентами системы. Каждой части аппаратных средств системы, например, компьютеру или датчику, на диаграмме размещения соответствует узел. Соединения узлов означают наличие в системе соответствующих коммуникационных каналов. Внутри узлов указывают размещенные на данном оборудовании программные компоненты разрабатываемой программной системы, сохраняя указанные на диаграмме компонентов отношения зависимости.
С точки зрения диаграммы размещения локальная и глобальная сети - это тоже узлы, которые обладают некоторой спецификой. На рис. 14.27 показаны условные обозначения узлов (процессора и устройства) на диаграмме размещения.
Рис. 14.27. Условные обозначения диаграммы размещения: а - процессор (компьютер). б - устройство
Пример 14.9. Разработать диаграмму размещения для системы учета успеваемости студентов.
Локальная сеть деканата связывает сервер деканата и компьютеры декана, его заместителей и сотрудников деканата, отвечающих за занесение информации в базу данных. Серверную часть системы и базу данных целесообразно поместить на сервер деканата. На компьютерах локальной сети в этом случае будут функционировать соответствующие клиентские части приложения (рис. 14.28).
Рис. 14.28. Диаграмма размещения в локальной сети системы учета успеваемости студентов
Методы доказательства правильности программ.
В общем случае проблема построения алгоритма, доказывающего правильность произвольной программы, не разрешима. Этим объясняется подход к ее решению, ориентированный на разработку методов верификации конкретных классов программ. Несмотря на большое разнообразие современных методов доказательства ПП, можно проследить их связь со ставшими классическими аксиоматическим подходом, методом индуктивных выражений и др. Остановимся подробнее на каждом из них.
Метод индуктивных утверждений Флойда.
Исторически первой системой верификации программ явился метод ИУ Р.Флойда. Аналогичные мысли о верификации в те же годы высказал П. Наур.
Идея метода состоит в следующем: программа в некоторых точках снабжается утверждениями относительно состояния ее переменных. Такими точками являются вход в программу (утверждение в этой точке называется входным предикатом), выход (здесь формулируется выходной предикат), промежуточные точки, утверждения в которых выполняются тогда, когда управление их достигает. Совокупности таких утверждений, заданные для всевозможных путей в программе, называются условиями верификации. Суть метода заключается в демонстрации того, что из входного предиката и преобразования, выполняемого на первом шаге, следует истинность утверждения, сформулированного в следующей точке, и т. д., вплоть до выполнения выходного предиката. Противоречие на любом шаге служит сигналом о наличии ошибки. Доказать ПП по Флойду -- значит показать, что истинность выходного предиката вытекает из истинности входного предиката в цепочке истинности всех промежуточных импликаций. Такой индуктивный процесс верификации программы и дал название методу.
Метод Флойда ориентирован на доказательство ПП из класса стандартных схем и стандартных схем с массивами. Объектом верификации выступают программы, представленные в виде блок-схем.
Метод ИУ Флойда, будучи исторически первой системой верификации, ориентирован на доказательство ПП довольно узкого класса и применим только для этой цели: он не позволяет в случае появления противоречия определить, является ли оно следствием ошибки в программе, или же ошибка содержится в самом доказательстве или в индуктивных утверждениях. Процесс демонстрации истинности условий верификации и их генерация осуществляется вручную и неудобен для автоматизации. Тем не менее с помощью этого метода удалось доказать правильность нескольких нетривиальных алгоритмов. Наиболее интересны доказательство Р. Лондоном алгоритма сортировки дерева, а также многочисленные числовые и нечисловые примеры Э Дейкстры. Подход Флойда используется при проектировании программ обработки данных методом формализованных технических заданий. В процессе проектирования обосновывается правильность результатов посредством установления соответствия между техническим заданием и его реализацией и приводятся определения различных свойств проектируемых объектов. Анализ результатов проектирования выполняется путем математического исследования и доказательства соответствующих утверждений.
Предложенные Флойдом идеи и введенные понятия служат основой большинства современных систем верификации программ, проведение которой в последние годы становится все более традиционным. В частности, необходимыми этапами процесса верификации являются следующие:
Формулировка утверждений о состоянии переменных программы в некоторых ее точках.
Генерация условий верификации по программе, снабженном указанной информацией (такую программу в дальнейшем будем называть аннотированной).
Доказательство непротиворечивости полученных условий верификации.
Доказательство завершимости программы (в процессе доказательства правильности или отдельно).
Метод Хора доказательства правильности программ.
Идеи Флойда нашли дальнейшее развитие в аксиоматическом подходе к доказательству ПП, предложенном К. Хором. Первоначально система Хора была ориентирована на доказательство правильности так называемых While-программ, для которых операторы goto недопустимы.
Следуя Флойду, Хоор вводит утверждения относительно состояний переменных программы до и после выполнения одного или нескольких операторов, называемые пред- и пост-условиями соответственно. Эта форма определения семантики получила название «индуктивных выражений».
Правила верификации в системе Хоора состоят из аксиомы присваивания, описывающей преобразование информационной среды, вызванное оператором присвоить, и правил вывода, с помощью которых выражения для отдельных операторов могут объединяться в большие фрагменты программ.
Виды контроля качества разрабатываемого программного обеспечения.
Недостаточно выполнить проектирование и кодирование программного обеспечения, необходимо также обеспечить его соответствие требованиям и спецификациям. Многократно проводимые исследования показали, что чем раньше обнаруживаются те или иные несоответствия или ошибки, тем больше вероятность их правильного исправления (рис. 16.1, а) и ниже его стоимость (рис. 16.1, б).
Рис 16.1. Зависимость вероятности правильного исправления (а) и его стоимости от этапа разработки (б)
Современные технологии разработки программного обеспечения предусматривают раннее обнаружение ошибок за счет выполнения контроля результатов всех этапов и стадий разработки. На начальных этапах такой контроль осуществляют в основном вручную или с использованием CASE-средств, на последних - он принимает форму тестирования.
Тестирование - это процесс выполнения программы, целью которого является выявление ошибок. Никакое тестирование не может доказать отсутствие ошибок в хоть сколько-нибудь сложном программном обеспечении. Для такого программного обеспечения выполнение полного тестирования, т. е. задания всех возможных комбинаций исходных данных, становится невозможным, а, следовательно, всегда имеется вероятность того, что в программном обеспечении остались не выявленные ошибки. Однако соблюдение основных правил тестирования и научно обоснованный подбор тестов может уменьшить их количество.
Примечание. Обычно на вопрос о цели тестирования начинающие программисты отвечают, что целью тестирования является «доказательство правильности программы». Это абсолютно неверное мнение. Г. Майерс предлагает очень удачную аналогию для пояснения этого положения. Представьте себе, что вы пришли на прием к врачу и пожаловались на боль в боку. Врач выслушал вас и направил на обследование. Через некоторое время вы возвращаетесь к врачу с ворохом заключений и результатов анализов, и во всех этих бумагах написано, что все исследуемые параметры у вас в норме. Но бок то болит, значит, что-то не в порядке, хотя анализы этого и не показывают... Так и сложное программное обеспечение, безошибочно работающее на всех тестовых наборах, может содержать и обычно содержит некоторое количество ошибок.
Процесс разработки программного обеспечения, в том виде, как он определяется в современной модели жизненного цикла программного обеспечения, предполагает три стадии тестирования:
автономное тестирование компонентов программного обеспечения;
комплексное тестирование разрабатываемого программного обеспечения;
системное или оценочное тестирование на соответствие основным критериям качества.
Для повышения качества тестирования рекомендуется соблюдать следующие основные принципы:
предполагаемые результаты должны быть известны до тестирования;
следует избегать тестирования программы автором;
необходимо досконально изучать результаты каждого теста;
необходимо проверять действия программы на неверных данных;
* необходимо проверять программу на неожиданные побочные эффекты на неверных данных.
Следует также иметь в виду, что вероятность наличия необнаруженных ошибок в части программы пропорциональны количеству ошибок уже найденных в этой части.
Формирование тестовых наборов, основные подходы.
В соответствии с определением тестирования в начале данного параграфа, удачным следует считать тест, который обнаруживает хотя бы одну ошибку. С этой точки зрения хотелось бы использовать такие наборы тестов, каждый из которых с максимальной вероятностью может обнаружить ошибку.
Формирование набора тестов имеет большое значение, поскольку тестирование является одним из наиболее трудоемких этапов (от 30 до 60 % общей трудоемкости) создания программного продукта. Причем доля стоимости тестирования в общей стоимости разработки имеет тенденцию возрастать при увеличении сложности программного обеспечения и повышении требований к их качеству.
Существуют два принципиально различных подхода к формированию тестовых наборов: структурный и функциональный.
Структурный подход базируется на том, что известка структура тестируемого программного обеспечения, в том числе его алгоритмы («стеклянный ящик»). В этом случае тесты строят так, чтобы проверить правильность реализации заданной логики в коде программы.
Функциональный подход основывается на том, что структура программного обеспечения не известна («черный ящик»). В этом случае тесты строят, опираясь на функциональные спецификации. Этот подход называют также подходом, управляемым данными, так как при его использовании тесты строят па базе различных способов декомпозиции множества данных.
Наборы тестов, полученные в соответствии с методами этих подходов, обычно объединяют, обеспечивая всестороннее тестирование программного обеспечения.
Более подробное рассмотрение перечисленных вопросов начнем с обсуждения методов ручного контроля.
Ручной контроль программного обеспечения, методы ручного контроля.
Ручной контроль программного обеспечения
Ручной контроль, как указано выше, обычно используют на ранних этапах разработки. Все проектные решения, принятые на том или ином этапе, должны анализироваться с точки зрения их правильности и целесообразности как можно раньше, пока их можно легко пересмотреть. Поскольку возможность практической проверки подобных решений на ранних этапах разработки отсутствует, большое значение имеет их обсуждение, которое проводят в разных формах.
Различают статический и динамический подходы к ручному контролю. При статическом подходе анализируют структуру, управляющие и информационные связи программы, ее входные и выходные данные. При динамическом - выполняют ручное тестирование., т. е. вручную моделируют процесс выполнения программы на заданных исходных данных.
Исходными данными для таких проверок являются: техническое задание, спецификации, структурная и функциональная схемы программного продукта, схемы отдельных компонентов и т. д., а для более поздних этапов - алгоритмы и тексты программ, а также тестовые наборы.
Доказано, что ручной контроль способствует существенному увеличению производительности и повышению надежности программ и с его помощью можно находить от 30 до 70 % ошибок логического проектирования и кодирования. Следовательно, один или несколько из методов ручного контроля обязательно должны использоваться в каждом программном проекте.
Основными методами ручного контроля являются:
инспекции исходного текста,
сквозные просмотры,
проверка за столом,
оценки программ.
Инспекции исходного текста
Инспекции исходного текста представляют собой набор процедур и приемов обнаружения ошибок при изучении текста группой специалистов. В эту группу входят: автор программы, проектировщик, специалист по тестированию и координатор - компетентный программист, но не автор программы. Общая процедура инспекции предполагает следующие операции:
участникам группы заранее выдается листинг программы и спецификация на нее;
программист рассказывает о логике работы программы и отвечает на вопросы инспекторов;
программа анализируется по списку вопросов для выявления исторически сложившихся общих ошибок программирования.
Список вопросов для инспекций исходного текста зависит, как от используемого языка программирования, так и от специфики разрабатываемого программного обеспечения. В качестве примера ниже приведен список вопросов, который можно использовать при анализе правильности программ, написанных на языке Pascal.
I. Контроль обращений к данным
Все ли переменные инициализированы?
Не превышены ли максимальные (или реальные) размеры массивов и строк?
Не перепутаны ли строки со столбцами при работе с матрицами?
Присутствуют ли переменные со сходными именами?
Используются ли файлы? Если да, то при вводе из файла проверяется ли завершение файла?
Соответствуют ли типы записываемых и читаемых значений?
*Использованы ли нетипизированные переменные, открытые массивы, динамическая память? Если да, то соответствуют ли типы переменных при «наложении» формата? Не выходят ли индексы за границы массивов?
2. Контроль вычислений
Правильно ли записаны выражения (порядок следования операторов)?
Корректно ли выполнены вычисления над неарифметическими переменными?
Корректно ли выполнены вычисления с переменными различных типов (в том числе с использованием целочисленной арифметики)?
Возможно ли переполнение разрядной сетки или ситуация машинного нуля?
Соответствуют ли вычисления заданным требованиям точности?
Присутствуют ли сравнения переменных различных типов?
3. Контроль передачи управления
Будут ли корректно завершены циклы?
Будет ли завершена программа?
*Существуют ли циклы, которые не будут выполняться из-за нарушения условия входа? Корректно ли продолжатся вычисления?
*Существуют ли поисковые циклы? Корректно ли отрабатываются ситуации «элемент найден» и «элемент не найден»?
4. Контроль межмодульных интерфейсов
Соответствуют ли списки параметров и аргументов по порядку, типу, единицам измерения?
Не изменяет ли подпрограмма аргументов, которые не должны изменяться?
*Не происходит ли нарушения области действия глобальных и локальных переменных с одинаковыми именами?
Кроме непосредственного обнаружения ошибок, результаты инспекции позволяют программисту увидеть другие сделанные им ошибки, получить возможность оценить свой стиль программирования, выбор алгоритмов и методов тестирования. Инспекция является способом раннего выявления частей программы, с большей вероятностью содержащих ошибки, что позволяет при тестировании уделить внимание именно этим частям.
Сквозные просмотры
Сквозной просмотр, как и инспекция, представляет собой набор способов обнаружения ошибок, осуществляемых группой лиц, просматривающих текст программы. Такой просмотр имеет много общего с процессом инспектирования, но отличается процедурой и методами обнаружения ошибок. Группа по выполнению сквозного контроля состоит из трех-пяти человек: председатель или координатор, секретарь, фиксирующий все ошибки, специалист по тестированию, программист и независимый эксперт. Сквозной просмотр предполагает выполнение следующих процедур:
участникам группы заранее выдают листинг программы и спецификацию на нее;
участникам заседания предлагают несколько тестов;
участники заседания мысленно выполняют каждый тест в соответствии с логикой программы, при этом состояние программы (значения переменных) отслеживается на бумаге или доске;
при необходимости программисту задают вопросы о логике проектирования и принятых допущениях.
В большинстве сквозных просмотров при выполнении самих тестов находят меньше ошибок, чем при опросе программиста.
Проверка за столом
Исторически данный метод ручного тестирования появился первым, так как он не требует наличия группы специалистов. Это - проверка исходного текста или сквозные просмотры, выполняемые одним человеком, который читает текст программы, проверяет его на наличие возможных ошибок по специальному списку часто встречающихся ошибок и «пропускает» через программу тестовые данные. Исходя из принципов тестирования, проверку за столом должен проводить человек, не являющийся автором программы. Метод наименее результативен, так как проверка представляет собой полностью неупорядоченный процесс, при ней отсутствует обмен мнениями и здоровая конкуренция.
Оценка программ
Этот метод непосредственно не связан с тестированием, но его использование также улучшает качество программирования. Его используют для анонимной оценки программы в терминах ее общего качества, простоты эксплуатации и ясности. Цель метода - обеспечить сравнительно объективную оценку и самооценку программистов.
Такая оценка выполняется следующим образом. Выбирается программист, который должен выполнять обязанности администратора процесса. Администратор набирает группу от шести до 20-ти участников, которые должны заниматься разработкой сходных программ. Каждому участнику предлагается представить для рассмотрения две программы, с его точки зрения -наилучшую и наихудшую. Отобранные программы случайным образом распределяются между участниками. Им дают по четыре программы - две наилучшие и две наихудшие, но не говорят, какие программы плохие, а какие - хорошие. Программист просматривает эти программы и заполняет анкету, в которой оценивает качество программ по семибалльной шкале.
После этого результаты оценки сверяют, а проверяющий дает общий комментарий и рекомендации по улучшению программ.
Структурное тестирование, критерии формирования тестовых наборов.
Структурное тестирование называют также тестированием по «маршрутам», так как в этом случае тестовые наборы формируют путем анализа маршрутов, предусмотренных алгоритмом. Под маршрутами при этом понимают последовательности операторов программы, которые выполняются при конкретном варианте исходных данных.
В основе структурного тестирования лежит концепция максимально полного тестирования всех маршрутов программы. Так, если алгоритм программы включает ветвление, то при одном наборе исходных данных может быть выполнена последовательность операторов, реализующая действия, которые предусматривает одна ветвь, а при втором - другая. Соответственно, для программы будут существовать маршруты, различающиеся выбранным при ветвлении вариантом.
Считают, что программа проверена полностью, если с помощью тестов удается осуществить выполнение программы по всем возможным маршрутам передач управления. Однако нетрудно видеть, что даже в программе среднего уровня сложности число неповторяющихся маршрутов может быть очень велико, и, следовательно, полное или исчерпывающее тестирование маршрутов, как правило, невозможно.
Структурный подход к тестированию имеет ряд недостатков. Так тестовые наборы, построенные по данной стратегии:
не обнаруживают пропущенных маршрутов;
не обнаруживают ошибок, зависящих от обрабатываемых данных, например, в операторе if (а - b) < eps - пропуск функции абсолютного значения abs проявится только, если а < b;
не дают гарантии, что программа правильна, например, если вместо сортировки по убыванию реализована сортировка по возрастанию.
Для формирования тестов программу представляют в виде графа, вершины которого соответствуют операторам программы, а дуги представляют возможные варианты передачи управления. Ниже приведен текст программы, которая определяет значение х в зависимости от значений параметров процедуры. Алгоритм этой программы представлен на рис. 16.2, а, а соответствующий граф передач управления - на рис. 16.2, б.
Procedure m (a, b: real; var x: real);
begin
if (a1) and (b=0) then x: =x/a;
if(a=2) or (x>l) then x: =x+l;
end;
Формирование тестовых наборов для тестирования маршрутов может осуществляться по нескольким критериям:
покрытие операторов;
покрытие решений (переходов);
покрытие условий;
покрытие решений/условий;
комбинаторное покрытие условий.
Рис. 16.2. Схема алгоритма процедуры примера (а) и ее граф передач управления (б)
Функциональное тестирование, методы формирования тестовых наборов.
Одним из способов проверки программ является тестирование с управлением по данным или по принципу «черного ящика». В этом случае программа рассматривается как «черный ящик», и целью тестирования является выяснение обстоятельств, в которых поведение программы не соответствует спецификации.
Для обнаружения всех ошибок в программе, используя управление по данным, необходимо выполнить исчерпывающее тестирование, т. е. тестирование на всех возможных наборах данных. Для тех же программ, где исполнение команды зависит от предшествующих ей событий, необходимо проверить и все возможные последовательности. Очевидно, что проведите исчерпывающего тестирования для подавляющего большинства случаев невозможно. Поэтому обычно выполняют «разумное» или «приемлемое» тестирование, которое ограничивается прогонами программы на небольшом подмножестве всех возможных входных данных. Этот вариант не дает гарантии отсутствия отклонений от спецификаций.
Правильно выбранный тест должен уменьшать, причем более чем на единицу, число других тестов, которые должны быть разработаны для обеспечения требуемого качества программного обеспечения.
При функциональном тестировании различают следующие методы формирования тестовых наборов:
эквивалентное разбиение;
анализ граничных значений;
анализ причинно-следственных связей;
предположение об ошибке.
Эквивалентное разбиение
Метод эквивалентного разбиения заключается в следующем. Область всех возможных наборов входных данных программы по каждому параметру разбивают на конечное число групп - классов эквивалентности. Наборы данных такого класса объединяют по принципу обнаружения одних и тех же ошибок: если набор какого-либо класса обнаруживает некоторую ошибку, то предполагается, что все другие тесты этого класса эквивалентности тоже обнаружат эту ошибку и наоборот.
Разработку тестов методом эквивалентного разбиения осуществляют в два этапа: на первом выделяют классы эквивалентности, а на втором - формируют тесты.
Выделение классов эквивалентности является эвристическим процессом, однако целесообразным считают выделять в отдельные классы эквивалентности наборы, содержащие допустимые и недопустимые значения некоторого параметра. При этом существует ряд правил:
если некоторый параметр х может принимать значения в интервале [1, 999], то выделяют один правильный класс 1 < х < 999 и два неправильных: х < 1 и х>999;
если входное условие определяет диапазон значений порядкового типа, например, «в автомобиле могут ехать от одного до шести человек», то определяется один правильный класс эквивалентности и два неправильных: ни одного и более шести человек;
если входное условие описывает множество входных значений и есть основания полагать, что каждое значение программист трактует особо, например, «типы графических файлов: bmp, jpeg, vsd», то определяют правильный класс эквивалентности для каждого значения и один неправильный класс, например, txt;
если входное условие описывает ситуацию «должно быть», например, «первым символом идентификатора должна быть буква», то определяется один правильный класс эквивалентности (первый символ - буква) и один неправильный (первый символ - не буква);
если есть основание считать, что различные элементы класса эквивалентности трактуются программой неодинаково, то данный класс разбивается на меньшие классы эквивалентности.
Анализ граничных значений
Граничные значения - это значения на границах классов эквивалентности входных значений или около них. Анализ показывает, что в этих местах резко увеличивается возможность обнаружения ошибок. Например, если в программе анализа вида треугольника было записано А + В ? С вместо А + В > С, то задание граничных значений приведет к ошибке: линия будет отнесена к одному из видов треугольника.
Применение метода анализа граничных значений требует определенной степени творчества и специализации в рассматриваемой проблеме. Тем не менее, существует несколько общих правил для применения этого метода:
если входное условие описывает область значений, то следует построить тесты для границ области и тесты с неправильными входными данными для ситуаций незначительного выхода за границы области, например, если описана область [-1.0, +1.0], то должны быть сгенерированы тесты: -1.0, + 1.0,-1.001 и+1.001;
если входное условие удовлетворяет дискретному ряду значений, то следует построить тесты для минимального и максимального значений и тесты, содержащие значения большие и меньшие этих двух значений, например, если входной файл может содержать от 1 до 255 записей, то следует проверить 0, 1, 255 и 256 записей;
Подобные документы
Этапы разработки технического задания. Спецификация программного обеспечения при структурном подходе. Дерево диаграмм, базовые понятия сетевой модели данных. Разработка пользовательского интерфейса. Разработка сценария диалога на основе экранных форм.
курсовая работа [2,0 M], добавлен 24.06.2012Схемы взаимодействия между заказчиком и разработчиком программного обеспечения. Качество программного обеспечения и определение основных критериев его оценка на современном этапе, особенности управления на стадиях жизненного цикла, анализ достаточности.
презентация [114,7 K], добавлен 14.08.2013Разработка программного обеспечения для корпоративного портала Череповецкого Государственного Университета. Выбор технологии, среды и языка программирования. Требования к составу и параметрам технических средств. Построение функциональных диаграмм.
дипломная работа [1,7 M], добавлен 09.11.2016Цели и задачи программной инженерии. Понятие программного обеспечения. Шесть принципов эффективного использования программного обеспечения. Виды программного обеспечения: общесистемное, сетевое и прикладное. Принципы построения программного обеспечения.
курсовая работа [30,4 K], добавлен 29.06.2010Описание среды разработки Microsoft Visual Studio. Поддерживаемые технологии и языки программирования. Возможности и особенности компьютеризированного тестирования человека. Проектирование программного обеспечения с использованием объектного подхода.
курсовая работа [3,0 M], добавлен 09.02.2013Оснащенность предприятия системным программным обеспечением, используемым для организации производственного процесса. Проектирование, внедрение и эксплуатация системного и прикладного программного обеспечения. Тестирование и отладка программного продукта.
отчет по практике [272,2 K], добавлен 29.12.2014Учета жильцов студенческого общежития. Требования к программному средству. Спецификация качества программного обеспечения. Проектирование архитектуры приложения и структуры данных, пользовательского интерфейса. Спецификация классов и типы данных.
курсовая работа [664,4 K], добавлен 26.08.2012Общая характеристика и основные структуры кодирования. Качество программного обеспечения, показатели в ГОСТ 28195 и ГОСТ Р ИСО/МЭК 9126, характеристика по функциональным возможностям. Основные критерии и процесс оценки качества программного обеспечения.
курсовая работа [219,5 K], добавлен 25.02.2012Тестирование как составляющая часть процесса отладки программного обеспечения, его роль для обеспечения качества продукта. Обнаружение ошибок в программах, выявление причин их возникновения. Подходы к формулированию критериев полноты тестирования.
курсовая работа [1,6 M], добавлен 20.12.2012Понятие программного обеспечения, вопросы его разработки и использования. Общая характеристика системного программного обеспечения и работа операционной системы. Специфика процесса управления разработкой программного обеспечения и его особенности.
курсовая работа [636,2 K], добавлен 23.08.2011