- •З курсу
- •З курсу
- •Содержание
- •Часть I. Инженерные основы программного обеспечения 10
- •Часть II. Требования к программному обеспечению 33
- •Часть III. Моделирование программного обеспечения 52
- •Часть IV. Технологии разработки программного обеспечения 124
- •Часть V. Письменная коммуникация. Документирование проекта Программного обеспечения 145
- •Часть VI. Управление проектом программного обеспечения 192
- •Предисловие
- •Часть I. Инженерные основы программного обеспечения
- •1. Введение в программную инженерию
- •1.1. Вопросы и ответы об инженерии программного обеспечения
- •1.2. Профессиональные и этические требования к специалистам по программному обеспечению
- •2. Системотехника вычислительных систем
- •2.1. Интеграционные свойства систем
- •2.2. Система и ее окружение
- •2.3. Моделирование систем
- •2.4. Процесс создания систем
- •2.5. Приобретение систем
- •3. Процесс создания программного обеспечения
- •3.1. Модели процесса создания программного обеспечения
- •3.2. Итерационные модели разработки программного обеспечения
- •3.3. Спецификация программного обеспечения
- •3.4. Проектирование и реализация программного обеспечения
- •3.5. Эволюция программных систем
- •3.6. Автоматизированные средства разработки программного обеспечения
- •4. Технологии производства программного обеспечения
- •Часть II. Требования к программному обеспечению
- •5. Требования к программному обеспечению
- •5.1. Функциональные и нефункциональные требования
- •5.2. Пользовательские требования
- •5.3. Системные требования
- •5.4. Документирование системных требований
- •6. Разработка требований
- •6.1. Анализ осуществимости
- •6.2. Формирование и анализ требований
- •6.3. Аттестация требований
- •6.4. Управление требованиям
- •7. Матрица требований. Разработка матрицы требований
- •Часть III. Моделирование программного обеспечения
- •8. Архитектурное проектирование
- •8.1. Структурирование системы
- •8.2. Модели управления
- •8.3. Модульная декомпозиция
- •8.4. Проблемно-зависимые архитектуры
- •9. Архитектура распределенных систем
- •9.1. Многопроцессорная архитектура
- •9.2. Архитектура клиент/сервер
- •9.3. Архитектура распределенных объектов
- •9.4. Corba
- •10. Объектно-ориентированное проектирование
- •10.1. Объекты и классы объектов
- •10.2. Процесс объектно-ориентированного проектирования
- •10.2.1. Окружение системы и модели ее использования
- •10.2.2. Проектирование архитектуры
- •10.2.3. Определение объектов
- •10.2.4. Модели архитектуры
- •10.2.5. Специфицирование интерфейсов объектов
- •10.3. Модификация системной архитектуры
- •11. Проектирование систем реального времени
- •11.1. Проектирование систем реального времени
- •11.2. Управляющие программы
- •11.3. Системы наблюдения и управления
- •11.4. Системы сбора данных
- •12. Проектирование с повторным использованием компонентов
- •12.1. Покомпонентная разработка
- •12.2. Семейства приложений
- •12.3. Проектные паттерны
- •13. Проектирование интерфейса пользователя
- •13.1. Принципы проектирования интерфейсов пользователя
- •13.2. Взаимодействие с пользователем
- •13.3. Представление информации
- •13.4. Средства поддержки пользователя
- •13.5. Оценивание интерфейса
- •Часть IV. Технологии разработки программного обеспечения
- •14. Жизненный цикл программного обеспечения: модели и их особенности
- •14.1. Каскадная модель жизненного цикла
- •14.2. Эволюционная модель жизненного цикла
- •14.2.1. Формальная разработка систем
- •14.2.2. Разработка программного обеспечения на основе ранее созданных компонентов
- •14.3. Итерационные модели жизненного цикла
- •14.3.1 Модель пошаговой разработки
- •14.3.2 Спиральная модель разработки
- •15. Методологические основы технологий разработки программного обеспечения
- •16. Методы структурного анализа и проектирования программного обеспечения
- •17. Методы объектно-ориентированного анализа и проектирования программного обеспечения. Язык моделирования uml
- •Часть V. Письменная коммуникация. Документирование проекта Программного обеспечения
- •18. Документирование этапов разработки программного обеспечения
- •19. Планирование проекта
- •19.1 Уточнение содержания и состава работ
- •19.2 Планирование управления содержанием
- •19.3 Планирование организационной структуры
- •19.4 Планирование управления конфигурациями
- •19.5 Планирование управления качеством
- •19.6 Базовое расписание проекта
- •20. Верификация и аттестация программного обеспечения
- •20.1. Планирование верификации и аттестации
- •20.2. Инспектирование программных систем
- •20.3. Автоматический статический анализ программ
- •20.4. Метод "чистая комната"
- •21. Тестирование программного обеспечения
- •21.1. Тестирование дефектов
- •21.1.1. Тестирование методом черного ящика
- •21.1.2. Области эквивалентности
- •21.1.3. Структурное тестирование
- •21.1.4. Тестирование ветвей
- •21.2. Тестирование сборки
- •21.2.1. Нисходящее и восходящее тестирование
- •21.2.2. Тестирование интерфейсов
- •21.2.3. Тестирование с нагрузкой
- •21.3. Тестирование объектно-ориентированных систем
- •21.3.1. Тестирование классов объектов
- •21.3.2. Интеграция объектов
- •21.4. Инструментальные средства тестирования
- •Часть VI. Управление проектом программного обеспечения
- •22. Управление проектами
- •22.1. Процессы управления
- •22.2. Планирование проекта
- •22.3. График работ
- •22.4. Управление рисками
- •23. Управление персоналом
- •23.1. Пределы мышления
- •23.1.1. Организация человеческой памяти
- •23.1.2. Решение задач
- •23.1.3. Мотивация
- •23.2. Групповая работа
- •23.2.1. Создание команды
- •23.2.2. Сплоченность команды
- •23.2.3. Общение в группе
- •23.2.4. Организация группы
- •23.3. Подбор и сохранение персонала
- •23.3.1. Рабочая среда
- •23.4. Модель оценки уровня развития персонала
- •24. Оценка стоимости программного продукта
- •24.1. Производительность
- •24.2. Методы оценивания
- •24.3. Алгоритмическое моделирование стоимости
- •24.3.1. Модель сосомо
- •24.3.2. Алгоритмические модели стоимости в планировании проекта
- •24.4. Продолжительность проекта и наем персонала
- •25. Управление качеством
- •25.1. Обеспечение качества и стандарты
- •25.1.1. Стандарты на техническую документацию
- •25.1.2. Качество процесса создания программного обеспечения и качество программного продукта
- •25.2. Планирование качества
- •25.3. Контроль качества
- •25.3.1. Проверки качества
- •25.4. Измерение показателей программного обеспечения
- •25.4.1. Процесс измерения
- •25.4.2. Показатели программного продукта
- •26. Надежность программного обеспечения
- •26.1. Обеспечение надежности программного обеспечения
- •26.1.1 Критические системы
- •26.1.2. Работоспособность и безотказность
- •26.1.3. Безопасность
- •26.1.4. Защищенность
- •26.2. Аттестация безотказности
- •26.3. Гарантии безопасности
- •26.4. Оценивание защищенности программного обеспечения
- •27. Совершенствование производства программного обеспечения
- •27.1. Качество продукта и производства
- •27.2. Анализ и моделирование производства
- •27.2.1. Исключения в процессе создания по
- •27.3. Измерение производственного процесса
- •27.4. Модель оценки уровня развития
- •27.4.1. Оценивание уровня развития
- •27.5. Классификация процессов совершенствования
21.2.2. Тестирование интерфейсов
Как правило, тестирование интерфейса выполняется в тех случаях, когда модули или подсистемы интегрируются в большие системы. Каждый модуль или подсистема имеет заданный интерфейс, который вызывается другими компонентами системы. Цель тестирования интерфейса – выявить ошибки, возникающие в системе вследствие ошибок в интерфейсах или неправильных предположений об интерфейсах.
Схема тестирования интерфейса показана на рис. 21.10. Стрелки в верхней части схемы означают, что контрольные тесты применяются не к отдельным компонентам, а к подсистемам, полученным в результате комбинирования этих компонентов.
Данный тип тестирования особенно важен в объектно-ориентированном проектировании, в частности при повторном использовании объектов и классов объектов. Объекты в значительной степени определяются с помощью интерфейсов и могут повторно использоваться в различных комбинациях с разными объектами и в разных системах. Во время тестирования отдельных объектов невозможно выявить ошибки интерфейса, так как они являются скорее результатом взаимодействия между объектами, чем изолированного поведения одного объекта.
Рис. 21.10. Тестирование интерфейсов
Между компонентами программы могут быть разные типы интерфейсов и соответственно разные типы ошибок интерфейсов.
1. Параметрические интерфейсы. Интерфейсы, в которых ссылки на данные и иногда функции передаются в виде параметров от одного компонента к другому.
2. Интерфейсы разделяемой памяти. Интерфейсы, в которых какой-либо блок памяти совместно используется разными подсистемами. Одна подсистема помещает данные в память, а другие подсистемы используют эти данные.
3. Процедурные интерфейсы. Интерфейсы, в которых одна подсистема инкапсулирует набор процедур, вызываемых из других подсистем. Такой тип интерфейса имеют объекты и абстрактные типы данных.
4. Интерфейсы передачи сообщений. Интерфейсы, в которых одна подсистема запрашивает сервис у другой подсистемы посредством передачи ей сообщения. Ответное сообщение содержит, результаты выполнения сервиса. Некоторые объектно-ориентированные системы имеют такой тип интерфейсов; например, так работают системы клиент/сервер.
Ошибки в интерфейсах являются наиболее распространенными типами ошибок в сложных системах и делятся на три класса.
• Неправильное использование интерфейсов. Компонент вызывает другой компонент и совершает ошибку при использовании его интерфейса. Данный тип ошибки особенно распространен в параметрических интерфейсах; например, параметры могут иметь неправильный тип, следовать в неправильном порядке или же иметь неверное количество параметров.
• Неправильное понимание интерфейсов. Вызывающий компонент, в который заложена неправильная интерпретация спецификации интерфейса вызываемого компонента, предполагает определенное поведение этого компонента. Если поведение вызываемого компонента не совпадает с ожидаемым, поведение вызывающего компонента становится непредсказуемым. Например, если программа бинарного поиска вызывается для поиска заданного элемента в неупорядоченном массиве, то в работе программы произойдет сбой.
• Ошибки синхронизации. Такие ошибки встречаются в системах реального времени, где используются интерфейсы разделяемой памяти или передачи сообщений. Подсистема – производитель данных и подсистема – потребитель данных могут работать с разной скоростью. Если при проектировании интерфейса не учитывать этот фактор, потребитель может, например, получить доступ к устаревшим данным, потому что производитель к тому моменту еще не успел обновить совместно используемые данные.
Тестирование дефектов интерфейсов сложно, поскольку некоторые ошибки могут проявиться только в необычных условиях. Например, пусть некий объект реализует очередь в виде структуры списка фиксированного размера. Вызывающий его объект при вводе очередного элемента не проверяет переполнение очереди, так как предполагает, что очередь реализована как структура неограниченного размера. Такую ситуацию можно обнаружить только во время выполнения специальных тестов: специально вызывается переполнение очереди, которое приводит к непредсказуемому поведению объекта.
Другая проблема может возникнуть из-за взаимодействий между ошибками в разных программных модулях или объектах. Ошибки в одном объекте можно выявить только тогда, когда поведение другого объекта становится непредсказуемым. Например, для получения сервиса один объект вызывает другой объект и полагает, что полученный ответ правильный. Если объект неправильно понимает вычисленные значения, возвращаемое значение может быть достоверным, но неправильным. Такие ошибки можно выявить только тогда, когда оказываются неправильными дальнейшие вычисления.
Вот несколько общих правил тестирования интерфейсов.
1. Просмотрите тестируемый код и составьте список всех вызовов, направленных к внешним компонентам. Разработайте такие наборы тестовых данных, при которых параметры, передаваемые внешним компонентам, принимают крайние значения из диапазонов их допустимых значений. Использование экстремальных значений параметров с высокой вероятностью обнаруживает несоответствия в интерфейсах.
2. Если между интерфейсами передаются указатели, всегда тестируйте интерфейс с нулевыми параметрами указателя.
3. При вызове компонента через процедурный интерфейс используйте тесты, вызывающие сбой в работе компонента. Одна из наиболее распространенных причин ошибок в интерфейсе – неправильное понимание спецификации компонентов.
4. В системах передачи сообщений используйте тесты с нагрузкой, которые рассматриваются в следующем разделе. Разрабатывайте тесты, генерирующие в несколько раз большее количество сообщений, чем будет в обычной работе системы. Эти же тесты позволяют обнаружить проблемы синхронизации.
5. При взаимодействии нескольких компонентов через разделяемую память разрабатывайте тесты, которые изменяют порядок активизации компонентов. С помощью таких тестов можно выявить сделанные программистом неявные предположения о порядке использования компонентами разделяемых данных.
Обычно статические методы тестирования более рентабельны, чем специальное тестирование интерфейсов. В языках со строгим контролем типов, например Java, многие ошибки интерфейсов помогает обнаружить компилятор. В языках со слабым контролем типов (например, С) ошибки интерфейса может выявить статический анализатор, такой как LINT. Кроме того, при инспектировании программ можно сосредоточиться именно на проверке интерфейсов компонентов.