ТЕХНОЛОГИЯ РАЗРАБОТКИ ПРИКЛАДНОГО ПРОГРАММНОГО ОБЕСПЕЧЕНИЯ
Соловьев С. В., Цой Р. И., Гринкруг Л. С.,
Зачастую разработчики, в процессе создания программного обеспечения (ПО), достаточно быстро переходят к построению системы и по ряду направлений действительно достигают заметного прогресса. Но в результате оказывается, что несмотря на затраченные усилия, клиент так и не получает ту систему, которую он хотел. Так как же определить, что создается «правильная» система? Ответить на данный вопрос помогут верификация и проверка правильности. Стандарт IEEE (1994) определяет верификацию следующим образом. Процесс оценивания системы или компонента с целью определить, удовлетворяют ли результаты некой фазы условиям, наложенным в начале данной фазы (IEEE 1012-1986, §2, 1994).
В значительной мере этому способствует применение эффективных процессов разработки программного обеспечения, а также осуществление анализа. Например, можно исследовать требования и убедиться, что они корректно, полно и сжато выражают более высокоуровневые потребности пользователей. Затем можно убедиться, что проектирование проводилось на основании требований и прецедентов, и полученный технический проект является полным и не имеет лишних элементов. В некоторых ситуациях анализ сокращается до просмотров и ревизий. В других случаях можно использовать модели и автоматизированные средства, чтобы проверить полноту, семантику и т.д.
В процессе разработки никогда не удается избежать изменений. Поэтому так же будут рассмотрены природа изменений и способы внесения и управления ими, которые позволяют не выпустить проект из-под контроля.
Верификация
При проектировании и реализации проекта команда должна иметь возможность проверять, не сбился ли он «с пути», т.е. соответствуют ли результаты потребностям клиента.
Постоянно выполняемый процесс проверки того, что каждый шаг разработки является корректным, удовлетворяет потребности последующей деятельности и не является излишним, мы будем называть верификацией (verification).
Таким образом, верификация в значительной мере является аналитической деятельностью, в ходе которой необходимо убедиться, что каждая стадия разработки (например, реализация в программном обеспечении одного или нескольких требований) соответствует заданным на предыдущей стадии требованиям. Как минимум, необходимо верифицировать следующее:
1. Описанные функции действительно соответствуют потребностям.
2. Производные от этих функций прецеденты и требования действительно поддерживают данные функции.
3. Прецеденты реализуются при проектировании.
4. Проектирование поддерживает функциональные и нефункциональные аспекты поведения системы.
5. Код действительно соответствует результатам и целям проектирования.
6. Тесты обеспечивают полное покрытие разработанных требований и прецедентов.
Итак, как узнать, что собой представляет наша разработка в целом? Нужен метод, который позволит гарантировать, что мы провели верификацию всего необходимого (и ничего лишнего!).
Для этого нужен план верификации и (желательно) некие автоматические средства, которые помогут выполнить его.
Одним из методов осуществления постоянного контроля верификационных действий является трассировка (traceability).
Независимо от того, как организована верификация, необходимо помнить, что суть ее в том, чтобы убедиться, что шаг, над которым мы работаем, имеет соответствующую предысторию и выполняется непротиворечивым и надежным способом. Более того, необходимо удостовериться, что каждое предпринимаемое нами действие необходимо, а ненужные шаги отсутствуют.
Затраты на верификацию
Неприятным моментом верификации является то, что можно потратить время на верификационную деятельность, которая не принесет отдачи. Поэтому нужен некий способ вычисления «экономических дивидендов» (return on investment - ROI) верификационной деятельности. Необходим подход, который поможет правильно вложить средства в проверку наших действий. Не хочется выполнять лишние проверки, но нельзя пропустить проверку жизненно важных аспектов.
Команда должна сконструировать и реализовать систему, соответствующую требованиям. Другими словами, команда должна иметь возможность убедиться, что планы реализации соответствуют по- требностям.
Верификация на всех уровнях
Верификацию можно применять на всех стадиях жизненного цикла разработки; методы не ориентированы на какую-либо одну фазу. Можно (и нужно) верифицировать элементы требований, проектирования, реализации, тестирования и другие важные элементы разработки, основываясь на результатах ROI-анализа. В той или иной степени верификацией придется заниматься на каждой стадии разработки. Она необходима, чтобы удостовериться в правильности следующих переходов:
от потребностей пользователя к функциям продукта;
от функций продукта к требованиям;
от требований к архитектуре;
от архитектуры к модели проектирования;
от модели проектирования к реализации;
от реализации к планированию тестов.
Отметим, что верификация важна для проектирования, так как возникшие на этой стадии ошибки сложно устранять на стадии реализации.
Рекомендуется во всех разработках проводить процесс верификации, который должен начинаться в начале разработки проекта и продолжаться на протяжении жизненного цикла. Верификация обязательна при разработке систем высокой надежности (систем жизнеобеспечения или таких систем, стоимость сбоя в которых недопустимо высока). Но каждый нетривиальный проект лишь выиграет от хорошо спланированной верификации.
Использование трассировки для поддержки верификации
Роль трассировки при верификации требований
Важным показателем качества реализации программы является возможность ее трассировки на стадиях спецификации, архитектуры, проектирования, реализации и тестирования. Способность отслеживать отношения и находить их связи при возникновении изменений является основной нитью многих современных высоконадежных программных процессов, особенно в медицине (устройства жизнеобеспечения) и других критически важных областях. Причина в том, что, как свидетельствуют данные, касающиеся безопасности, воздействие изменения часто в полной мере не отслеживается и незначительные изменения системы могут вызвать значительные проблемы с безопасностью и надежностью.
Стандарт IEEE (1994) предлагает следующее определение трассировки:
«Степень, до которой можно установить связь между двумя или большим числом продуктов процесса разработки, особенно продуктами, которые являются по отношению друг к другу предшествующим - последующим или главным подчиненным; например, степень соответствия между требованиями и проектом конкретного программного компонента» (IEEE 610.12-1990 §3).
Ключевым элементом трассировки является «отношение трассировки» (traceability relationship). Удобно определить это отношение с помощью простой модели, использующей понятия «трассируется к» (traced-to) «трассируется от» (traced-from). Например, одно или несколько требований к программному обеспечению создаются с целью поддержки некой функции, заданной в документе-концепции. Можно сказать, что программное требование трассируется от некоторой функции.
В зависимости от типов создаваемых требований данное отношение приобретает дополнительный смысл. Например, то, что некое требование к программному обеспечению «трассируется к» определенному тестовому примеру, означает, что данное требование «тестируется» этим тестовым примером. То, что описание объекта «трассируется от» конкретного программного требования, подразумевает, что это требование «реализуется» указанным объектом. Между этими элементами проекта имеются отношения вида один - ко - многим, многие - к - одному и многие - ко - многим.
Неявная и явная трассировка
Команда разработчиков может явным образом задавать отношения между элементами. Это явная трассировка ─ разработка отношений, основанная на соображениях команды. Например, связь, или отношение, между функцией продукта и прецедентом, осуществляющим поддержку этой функции, определяется исключительно решением команды о том, что такое отношение имеет смысл. Не существует внутренне присущей элементам связи между ними; только внешние решения могут привести к заданию этой связи.
С другой стороны, методология и структура модели могут задавать неявные отношения трассировки. Неявная трассировка может также возникнуть вследствие использования определенной парадигмы моделирования. Например, применяемые в процессе разработки инструментальные средства моделирования могут автоматически обеспечивать отношения трассировки между моделируемыми элементами. Если средство моделирования обеспечивает неявные связи между элементами модели прецедента и взаимодействующими с прецедентом акторами, существует реальная возможность использовать эти неявные отношения трассировки. Можно продолжить эту трассировку далее к реализации, трассируя кооперации прецедентов к объектам реализации.
Дополнительные возможности, предоставляемые трассировкой
Например, иногда полезно определить новый элемент, назвав его «спорный вопрос», и хранить все текущие нерешенные вопросы как подобные элементы проекта. Используя трассировку, можно связать спорные вопросы с пунктами, где они упоминаются. Например, если есть нерешенный вопрос о функциональных возможностях продукта, можно связать его с соответствующими функциями продукта и требованиями к программному обеспечению. Поддерживая связи «спорных вопросов», можно потом вернуться назад и найти все элементы проекта, связанные с вопросом, который только что решен. В процесс трассировки проекта можно также включить следующие элементы:
предположения и объяснения;
элементы действий;
запросы на новые/пересмотренные функции;
термины глоссария и акронимы;
библиографические ссылки.
Другими словами, трассировку можно использовать для того, чтобы понять отношения между элементами проекта. Следует трассировать все полезные отношения. Но всегда необходимо следить за балансом важности элементов трассировки и затрат на их поддержку.
Использование автоматических средств трассировки
Для задания трассировочных отношений полезно использовать автоматические средства трассировки. Используя автоматическое средство, можно получить множество дополнительных сведений о проекте. Например, после того как определены отношения между функциями и требованиями к программному обеспечению системы, можно отобразить матричную версию этих отношений.
После того как с помощью автоматического средства заданы все известные отношения, обязательным действием является проверка матрицы трассировки на наличие двух возможных индикаторов ошибок.
1. Если при просмотре некой строки не удается обнаружить никаких отношений трассировки, вероятно, еще не определено требование к программному обеспечению, отвечающее функции документа-концепции. Такая ситуация допустима, если функция не имеет отношения к программе. Тем не менее, пустые строки являются индикаторами возможных ошибок и нуждаются в тщательной проверке. Современные инструментальные средства управления требованиями должны предоставлять возможность автоматического проведения такой проверки.
2. Если в некотором столбце не оказывается отношений трассировки, вероятно, было создано требование к программному обеспечению, для которого нет требующей его функции продукта. Это может указывать на неправильное понимание роли программного требования, недостаток исходного документа-концепции, а также на то, что код неправильный, не соответствует системному требованию и в таком случае его следует удалить. В любом случае необходима тщательная проверка.
Работа без автоматических средств трассировки
Если в распоряжении нет автоматического средства трассировки, то возможно использовать для поддержки отношений трассировки электронные таблицы и базы данных. Многие матричные отношения можно легко обрабатывать с помощью простой электронной таблицы. Однако поддержка электронных таблиц представляет определенную проблему, особенно при обширных иерархиях отношений. Использование баз данных также накладывает ограничения в работе по сравнению с автоматическими средствами трассировки.
Таким образом, для поддержки отношений трассировки можно использовать электронные таблицы или базы данных, хотя это может значительно усложнить работу. Если проект небольшой, неудобства будут минимальны, и, может быть, имеет смысл использовать эти, более простые, средства. С другой стороны, не рекомендуется браться за более крупный проект, если в распоряжении нет специализированных автоматических средств трассировки.
Пропущенные отношения
Чтобы обнаружить пропущенные отношения, надо искать строки матрицы трассировки, которые показывают, что некая функция не связана ни с одним программным требованием (прецедентом).
При обнаружении «дыры» в отношениях нужно вернуться к исходному набору требований к продукту и связанным с ними программным требованиям /прецедентам.
Может оказаться, что связь была случайно пропущена при задании трассировки. В таком случае простое добавление новой связи и пересчет матрицы трассировки решат проблему. Ошибки такого типа часто встречаются на ранних стадиях проекта.
Но может выясниться, что при разработке программных требований просто не удалось учесть потребности одной из необходимых функций продукта. В таком случае следует или исправить проект и добавить подходящие требования, отвечающие данной функции, или поместить пропущенную функцию в категорию «будущих», либо удалить вовсе.
В любом случае при верификации важно убедиться, что ни одна связь не пропущена и все элементы более низкого уровня, такие как программные требования/прецеденты, надлежащим образом связаны с более высокоуровневыми требованиями к продукту.
Кроме того, верификация может выявить следующее. При проверке столбцов матрицы трассировки могут обнаружиться столбцы, не связанные ни с одной строкой (функцией).
Подобные ситуации свидетельствуют, что для созданного прецедента (или требования) не существует связанной с ним функции продукта. Иными словами, требование является лишним. Как и ранее, следует проверить отношения трассировки.
Может оказаться, что связь пропущена случайно при задании трассировки. В таких случаях нужно просто добавить новую связь, пересчитать матрицу трассировки, и проблема будет решена.
Но может быть и так, что при задании функций продукта просто не были учтены потребности одного из необходимых требований к программному обеспечению. Такая ситуация может возникнуть, если есть определенные ограничения проектирования, которые необходимы при реализации, но меняют функции продукта. В таком случае необходимо исправить проект, чтобы учесть осуществимость и необходимость требований. Можно удалить соответствующее требование или поместить его в список «будущих». С другой стороны, при пересмотре проекта может оказаться, что пропущенную функцию следует поместить в категорию «будущих» или добавить уже сейчас.
При верификационном просмотре такого типа основное внимание уделяется тому, чтобы в проект не закрались беспричинные элементы. Опыт свидетельствует, что они значительно увеличивают объем проекта и редко способствуют повышению качества результата.
Стоит рассматривать исходные связи как некую точку отсчета при проведении верификации. После задания исходных связей и завершения проверки исходных строк/столбцов нужно провести формальные (или неформальные) проверки. Только после проведения, по крайней мере, одной полномасштабной проверки и внесения изменений можно считать, что верификация на данной фазе проведена.
Изменения связей, конечно же, неизбежны. Поэтому необходимо трактовать все связи как «живые», подверженные пересмотрам по мере продвижения проекта. Следует проводить проверки с целью верификации всякий раз, когда становится очевидно, что будущая, текущая или прошлая фаза внесла существенные изменения в трассировочные связи.
Проверка правильности системы
Стандарт IEEE (1994) определяет проверку правильности (validation) следующим образом.
Процесс оценивания системы или компонента во время или по окончании процесса разработки с целью определить, удовлетворяет ли она указанным требованиям (IEEE 1012-1986, §2, 1994).
Другими словами, проверка правильности призвана подтвердить, что реализованная система соответствует заданным требованиям.
Но данное определение недостаточно. Хотя тестирование на соответствие требованиям является, безусловно, важным шагом, все же существует вероятность, что предоставленная система окажется не такой, как хотел клиент. Это может быть связано с тем, что не удалось превратить туманное «облако» проблемы пользователя в организованную структуру, представленную требованиями. Проводя приемочные тесты на каждой итерации, можно минимизировать этот эффект.
Приемо-сдаточные испытания
Приемо-сдаточные испытания привлекают заказчика к процессу окончательной проверки правильности системы, чтобы убедиться, что «продукт работает именно так, как нужно клиенту». Для внешних заказчиков приемо-сдаточные испытания могут разрабатываться и выполняться в соответствии с условиями контракта.
Приемо-сдаточные испытания обычно основываются на определенном количестве «сценариев», которые пользователь задает и выполняет в среде использования. Клиент имеет право конструировать оригинальные способы проверки системы, чтобы убедиться, что система работает так, как ему необходимо. Если все сделано правильно, приемо-сдаточные испытания будут основываться на ключевых прецедентах, которые уже были определены и реализованы. Но при приемке эти прецеденты будут применяться в различных комбинациях при разных типах загрузки системы и при наличии других факторов среды - параллельная работа с другими приложениями, зависимость от ОС и т.д. - которые, скорее всего, присутствуют в среде пользователя.
В итеративном процессе разработки следует проводить приемочное тестирование при достижении различных важных вех в построении системы.
Тестирование с целью проверки правильности
Основной деятельностью при проверке правильности является тестирование. Но как должен выглядеть хороший план тестирования? Один из вариантов предлагается стандартом IEEE 829-1983, IEEE Standard for Software Test Documentation (IEEE, 1994). Данный стандарт содержит восемь образцов документов, которыми следует руководствоваться при выборе методологии тестирования, проведении тестов, сообщении о результатах и устранении аномалий. Есть и другие методологии, использующие иные подходы, но все они сходятся в главном.
Процесс разработки должен включать в себя планирование действий по тестированию.
Процесс разработки должен предусматривать выделение времени и ресурсов для проектирования тестов. Полезно иметь общий шаблон, разработанный таким образом, чтобы проект каждого отдельного теста больше внимания уделял его индивидуальным особенностям.
Необходимо предусмотреть выделение времени и ресурсов на выполнение тестов, как на уровне отдельных тестов (при необходимости), так и на общесистемном уровне.
Трассировка при проверке правильности
При проверке правильности трассировка должна ответить на два важных вопроса.
1. Достаточно ли тестов, чтобы проверить все, что нуждается в тестировании?
2. Нет ли лишних или ненужных тестов?
В процессе проверки правильности выясняется, действительно ли продукт работает так, как предполагалось. На этом этапе больше не проверяются отношения различных спецификаций и элементов проектирования; вместо этого рассматриваются отношения между тестами (и их результатами) и тестируемой системой. Как и при верификации, цель состоит в том, чтобы удостовериться, что все элементы, которые в этом нуждаются, тестируются на соответствие требованиям.
Основанное на требованиях тестирование
Чтобы добиться высокого качества результатов тестирования, необходимо протестировать систему на соответствие требованиям. Конечно, может оказаться полезным провести тестирование модулей для различных элементов проекта. Но тестирование отдельных модулей не может гарантировать, что система в целом работает так, как нужно. Сложные разработки могут успешно пройти все тесты модулей, но не выдержать испытаний в качестве системы. Это объясняется тем, что модули взаимодействуют в более сложных вариантах поведения, а результирующая система не была адекватно протестирована на соответствие системным требованиям.
Трассировка тестовых примеров
Методы трассировки позволяют убедиться, что тестовые примеры полностью покрывают все необходимые функциональные возможности системы. Нужно создать последовательности планов тестирования, которые можно связать с исходными системными требованиями и прецедентами.
Предположим, у нас имеется матрица трассировки, сопоставляющая тесты и прецеденты. Так же, как и при проведении верификации, можно исследовать данную матрицу, чтобы убедиться, что тестовые примеры надлежащим образом покрывают все системные спецификации. Аналогично можно связать тестовые примеры с прецедентами.
Пропущенные отношения проверки правильности
Итак, тестовые примеры были внесены в матрицы трассировки. Теперь нужно исследовать заданные связи, как это делалось при верификационных просмотрах.
Для выявления пропущенных отношений нужно искать строки матрицы трассировки, из которых видно, что определенная функция (или требование) не связана ни с каким тестом.
Выявив такую «дыру» в отношениях, необходимо проверить исходный набор требований к продукту и соответствующие прецеденты:
если окажется, что связь случайно пропущена при задании трассировки, нужно просто добавить новую связь и пересчитать матрицу трассировки. Подобные пропуски часто возникают на ранних стадиях задания трассировки проверки правильности;
если обнаружится, что при разработке тестовых примеров не удалось протестировать одну из необходимых функций продукта, может понадобиться пересмотреть проект, чтобы добавить подходящие тесты, соответствующие данной функции. В отличие от аналогичного случая при верификации, не рекомендуется отмечать пропущенные тестовые примеры как «будущие» действия. Если есть не протестированная функция, можно не сомневаться, что заказчик будет ее тестировать.
При проверке правильности трассировка помогает удостовериться, что никакие связи не пропущены и все тесты продукта надлежащим образом связаны с более высокоуровневыми требованиями к продукту.
Как и при верификации, в ходе проверки правильности можно при просмотре столбцов трассировочной матрицы обнаружить столбцы, не связанные ни с одним элементом строки. Это означает, что был создан тестовый пример, для которого не существует связанной с ним функции продукта. Иначе говоря, тест выглядит лишним. Как и ранее, следует рассмотреть отношения трассировки:
возможно, связь была, случайно пропущена при задании трассировки. Если так, нужно просто добавить новую связь и пересчитать матрицу трассировки. Такие пропуски часто возникают на ранних стадиях задания трассировки проверки правильности;
может оказаться, что при разработке функций продукта просто не были учтены потребности одного из необходимых программных тестов. Это может произойти в том случае, если определенные нефункциональные требования к реализации фактически меняют функции продукта. Тогда может понадобиться пересмотреть проект, чтобы учесть достижимость и необходимость требований. Как и при верификации, команде нужно будет принять решение, нужен ли данный тест вообще и, если нужен, какие трассировочные связи необходимы.
Применение метода анализа дивидендов для определения объема V&V-действий
Как и все остальное, инициирование и проведение V&V (Verification & Validation)-действий требуют определенных затрат. Поэтому необходимо ответить на вопрос: «Как провести анализ затрат/прибыли, чтобы увидеть, действительно ли полученные результаты того стоят?». Стоит планировать V&V-действия, исходя из ответов на следующие два вопроса.
1. Какими будут социальные или экономические последствия сбоя системы?
2. Какой необходим объем V&V-действий, чтобы гарантировать, что эти последствия не возникнут?
Безусловно, не желательно, что бы было проведено слишком много проверок в проекте, результаты которых имели для него минимальное значение. Но значительно хуже, если окажется, что проведенных проверок недостаточно. Это может привести даже к возврату продукта. Следовательно, нужен аналитический подход, который поможет выбрать соответствующий объем V&V-действий до того, как к ним приступать. Следует начать с рассмотрения вопросов «глубины» и «покрытия».
Глубина и покрытие V&V
Глубина определяет уровень детализации при проведении проверки элемента системы.
Глубина задает уровень детализации, выбранный для верификации или оценки элемента системы. В среднем, чем больше глубина, тем больше понадобится времени и средств для выполнения этих действий. Поэтому полезно убедиться, что для каждого элемента выбрана глубина проверки, которая соответствует важности элемента.
Не все элементы нуждаются в одинаковой глубине проверки. Например, для не основных элементов может быть достаточно просмотра или простого системного теста, а для критических может понадобиться масштабное прозрачное тестирование.
Можно выделить следующие методы проверки и предлагаемую ими глубину:
просмотр (Examination). Просматривается код или осуществляются некие измерения. Суть просмотра в том, что тестируемые элементы подвергаются заранее определенному минимально глубокому рассмотрению. Это считается минимальной глубиной проверки элемента;
сквозной контроль (Walkthrough). Осуществляющая проверку группа рассматривает все этапы работы элемента. В некотором смысле этот процесс является структурированным просмотром, выполняемым более широкой группой, которая ищет недостатки, упущения и т.п. в коде. Такой тип проверки обеспечивает большую глубину, чем простой просмотр;
независимые ревизии (Independent reviews). Этот метод аналогичен двум предыдущим. Группа независимых специалистов просматривает элемент и выявляет недоработки. В результате такая проверка может высветить дополнительные вопросы, которые не были замечены группой проекта;
тестирование черного ящика (black-box test). В данном случае элемент рассматривается как модуль, внутренняя структура которого неизвестна. Таким образом, можно поставлять ему вводы и наблюдать его выводы, чтобы убедиться, что элемент работает в соответствии с требуемыми стандартами. Такие тесты обычно выполняются с помощью специального контрольного кода или системных эмуляторов, а также других средств имитации и записи функционирования системы;
прозрачное тестирование (white-box test). При таком тестировании позволено «открыть белый ящик» и исследовать внутреннее устройство элемента. Большинство модулей кода имеет слишком много комбинаций возможных вариантов развития процесса вычислений, чтобы их можно было протестировать за разумное время. Поэтому, чтобы не тратить на прозрачное тестирование слишком много времени, необходимо применить к нему некую разумную концепцию тестирования. Общепринятым компромиссом является исследование каждой строки кода, но не всех возможных комбинаций магистральных путей. Такой тип проверки обычно требует значительного объема ресурсов и привлечения дополнительного персонала.
V&V-покрытие
Покрытие (зона действия, coverage) означает степень покрытия элементов системы V&V-действиями. В рамках V&V-деятельности можно применить к различным элементам методы трассировки. Например, можно трассировать требования к тестовым примерам, функции к прецедентам, прецеденты к реализации и т.д. Количество задаваемых трассировок и уровень конкретизации требований являются основными факторами при определении V&V-покрытия.
Иными словами, нужно решить, какие требования (как текстовые, так и в виде прецедентов), элементы реализации, тестовые примеры и т.д. необходимо рассмотреть.
Что подвергать верификации и проверке правильности
При составлении плана V&V необходимо решить, какие элементы следует подвергать верификации и проверке правильности, чтобы создать высококачественный продукт и при этом минимизировать общие затраты на его разработку. Есть несколько способов решения этого вопроса.
Вариант 1. Верифицировать и проверять правильность всех элементов.
В небольших проектах, где требуется достаточно высокий уровень качества предоставляемого продукта, можно выполнять V&V-процессы практически для всех элементов приложения. Преимущество данного подхода в его понятности и в одинаковой трактовке элементов разработки. Кроме того, не нужно проводить анализ перед началом разработки и строить предположения относительно стоимостных элементов V&V.
Вариант 2. Анализ рисков для определения необходимости V&V.
Одним из систематических подходов к выявлению важных элементов проекта является анализ рисков (hazard analysis) и связанные с ним действия по оценке рисков.
Анализ рисков представляет собой подробное исследование продукта с точки зрения пользователя. Его цель состоит в выявлении потенциальных недоработок проектирования (возможностей отказа, которые могут принести вред) и предоставлении производителю возможности исправить их до того, как продукт будет запушен в производство.
Разработчик должен рассмотреть различные типы ошибок, которые могут возникать в создаваемом продукте. Все потенциальные риски исследуются и фиксируются в специальном документе, что позволяет разработчику предложить стратегии проектирования, которые помогут их избежать.
На последующих стадиях жизненного цикла разработки продукта документ анализа рисков будет служить для фиксации, как потенциальных рисков, так и методов, применяемых для их уменьшения. Позднее при проверке правильности системы данный документ используется для того, чтобы убедиться, что все предполагаемые риски полностью учтены и устранены, а тестирование будет преимущественно направлено на эти области, для достижения более высокой степени гарантий.
В любом случае анализ рисков используется для того, чтобы решить, какие риски необходимо предотвратить в системе и каков объем необходимых для этого V&V-действий. Для элементов проектирования, имеющих, согласно документу анализа рисков, большое значение для общей безопасности и успеха разработки, следует обеспечить проведение полномасштабных V&V-действий. Для элементов, имеющих меньший или незначительный риск, можно уменьшить объем V&V-действий или вовсе пропустить их, хотя общее тестирование системы все равно необходимо.
Анализ рисков и анализ дивидендов (ROI)
Можно рассматривать анализ и оценку рисков, интерпретируя их как стандартный анализ затрат/прибыли, и использовать результаты анализа рисков в качестве исходной информации для стандартного анализа дивидендов (return on investment - ROI).
Сначала производятся оценки затрат (времени, ресурсов и денег) для действий по проверке некоего элемента или сегмента проекта. Эти затраты вводятся в стандартные экономические модели ROI, чтобы получить представление о затратах этапа. Затем выполняется оценка возможного воздействия предварительно выявленных в результате анализа рисков негативных последствий, которые могут возникнуть при неправильной работе элемента, не подвергавшегося V&V. После сравнения двух полученных результатов можно принять обоснованное решение о том, стоит ли проводить V&V-действия и какой должна быть их глубина.
В процессе работы над проектом невозможно избежать изменения требований к разрабатываемой системе. Есть несколько причин неизбежности изменений требований. Среди них внутренние факторы, которые мы можем контролировать, и внешние, которые не подвластны контролю со стороны разработчиков и пользователей.
Внешними факторами являются те источники изменений, которые команда проекта не может контролировать. Изменения возникают по следующим причинам:
произошли изменения проблемы, которую мы пытались решить с помощью новой системы. Возможно, возникли изменения в экономике, в правительственных инструкциях, на рынке или же изменились предпочтения потребителей. Из-за быстрых темпов развития технологии вполне вероятно, что такие изменения произойдут до того, как будет закончено решение исходной проблемы, описанной пользователем:
пользователи изменили свое мнение о том, чего они хотят от системы, или свои предпочтения. Это, в свою очередь, может произойти вследствие того, что предпочтения пользователей зависят от ситуации на рынке, экономики, различных инструкций и т.д.;
изменилась внешняя среда, что привело к появлению новых ограничений и/или новых возможностей. Одним из наиболее очевидных примеров изменения среды является постоянно происходящее совершенствование систем аппаратного и программного обеспечения;
вошла в строй новая система. Одним из самых неожиданных внешних факторов возникновения изменений является то, что само появление новой системы приводит к тому, что меняются требования к ней. Благодаря новой системе меняется поведение организации, старые способы выполнения действий больше не применяются; возникает потребность в новых типах информации и неизбежно разрабатываются новые требования к системе. Таким образом, сам факт ввода в строй новой системы выявляет новые требования к ней.
Процесс управления требованиями может быть полезен только в том случае, если он позволяет выявлять и решать проблему изменений. Невозможно предотвратить изменения, но можно научиться ими управлять.
Помимо внешних факторов, существует ряд внутренних, которые также приводят к возникновению изменений:
при первоначальном выявлении требований не удалось задать правильные вопросы нужным людям и в нужное время. Если процесс коснулся не всех заинтересованных лиц или им не были заданы правильные вопросы, это усугубляет проблему изменений, так как нет понимания истинных требований к системе;
не удалось создать практический процесс, позволяющий справиться с изменениями требований, которые являются нормой при пошаговой разработке. Это может привести к тому, что изменения накапливаются до тех пор, пока перед лицом разработчиков и пользователей не встанет проблема не возможности продолжать работу без осуществления переделок и внесения изменений.
Процесс управления изменениями
Поскольку изменения являются неотъемлемой частью процесса, а источники их поступления могут быть как внешними, так и внутренними, необходим процесс управления изменениями требований. Такой процесс дисциплинирует команду, позволяет ей выявлять изменения, производить анализ их воздействия и систематическим способом включать те из них, которые наиболее необходимы и приемлемы для системы. Рекомендуется включать в процесс обработки изменений, следующие шаги:
1. Осознать, что изменения неизбежны, и разработать план управления изменениями.
2. Сформировать базовый уровень требований.
3. Установить единый канал контроля изменений.
4. Использовать систему контроля изменений для их фиксации.
5. Обрабатывать изменения по иерархическому принципу.
Рассмотрим более подробно каждый из этих шагов.
Шаг 1. Осознать, что изменения неизбежны, и разработать план управления изменениями.
Команда должна признать, что изменения требований к системе неизбежны и даже необходимы. Изменения будут возникать, и команда, зная об этом, должна разработать соответствующий план управления изменениями, который разрешит внесение определенных изменений в исходный базовый уровень.
Шаг 2. Формирование базового уровня требований.
Ближе к концу фазы исследования жизненного цикла разработки команда должна скомпоновать все известные требования к системе. Процесс формирования базового уровня может заключаться в наложении контроля исправлений на документ-концепцию, программные требования и модели прецедентов, а также в публикации базового уровня для команды разработчиков. Собранные в этих документах отдельные требования создают базовый уровень информации о требованиях и предполагаемых прецедентах системы.
Этот простой шаг позволяет команде различать известные («старые») требования и новые (те, которые были добавлены, удалены или модифицированы). После задания базового уровня гораздо легче выявлять и обрабатывать новые требования. Запрос на новое требование можно сравнить с существующей базой и определить, где оно будет размещаться, и не будет ли оно конфликтовать с другими требованиями.
Однако упорядочение процесса внесения изменений не означает, что можно вносить их сколько угодно. С точки зрения, как пользователей, так и разработчиков гораздо проще, если удастся создать набор стабильных корректных требований. Даже при достаточно хорошо организованном процессе управления изменениями существуют ограничения на количество изменений, которые разработчик сможет учесть, особенно на стадиях проектирования и реализации. Как правило, коэффициент изменения требований во время разработки составляет 1-4 % в месяц. Но если его величина превышает 2 % в месяц, проект подвергается высокому риску «перемешивания» требований.
Шаг 3. Задание единого канала контроля изменений.
Хотя очевидно, что появление новой функции может оказать существенное влияние на требования к программному обеспечению, системную архитектуру, планы тестов и т.д., но и «простое изменение» кода может вызывать непредвиденные последствия. Кроме того, предлагаемая новая функция может устранять важную будущую функцию системы или затруднять ее реализацию (т.е. воздействие распространяется не только на текущую версию). Есть также трудности, связанные с графиком и бюджетом проекта, за которые отвечает руководство. Пожелания заказчиков о внесении изменений не предполагают официального изменения графика и бюджета, и следует инициировать процесс переговоров до того, как изменение будет принято.
Таким образом, очень важно, чтобы все изменения поступали по одному каналу, чтобы определить их воздействие на систему и принять официальное решение, стоит ли вносить это изменение в систему вообще. В небольшом проекте этим официальным каналом может быть лидер проекта, менеджер или кто-нибудь другой, кто «владеет» документом-концепцией, а также имеет полное представление о требованиях к системе и ее проекте.
В более крупных системах или в системах, где затрагиваются интересы множества заинтересованных лиц, такой официальный канал может состоять из нескольких человек (образующих совет по контролю над изменениями - Change Control Board, CCB), которые совместно несут ответственность за принимаемые решения и обладают знаниями и полномочиями, необходимыми для официального принятия запроса об изменении.
В любом случае изменение системы нельзя инициировать до тех пор, пока механизм контроля над изменениями не признает его «официальным».
Шаг 4. Использование системы контроля изменений для их фиксации.
Проще всего дело обстоит с внешними изменениями, которые производятся по запросу клиента. Их легко выявлять, и они будут естественным образом включены в проект руководством или органом, осуществляющим контроль над изменениями. Но во время разработки возникает огромное множество иных изменений системы.
Многие предлагаемые изменения, возникающие во время проектирования, кодирования и тестирования системы, могут казаться не связанными с требованиями (например, исправление ошибок кода или проектирования). Тем не менее, необходимо оценить их воздействие. А если подходит срок сдачи, следует даже принять сознательное решение о том, какие ошибки оставить в системе (из-за того, что их исправление может дестабилизировать систему в целом и тем самым поставить под угрозу дату сдачи), а какие - устранить. Помимо этого, многие ошибки могут влиять на требования, вызывать необходимость их согласования или устранения неоднозначности отдельного известного требования.
Иногда, даже непонятно, какой тип изменений запрашивается. Это особенно часто происходит, когда конечные пользователи жалуются на проблемы после окончания разработки или когда члены службы оперативной поддержки передают результаты анализа жалоб пользователя техническим разработчикам.
Команде следует разработать некую систему для фиксации всех запросов на изменения.
В любом случае необходимо проанализировать ситуацию, а также принять решение о том, где изменение будет реализовано в иерархии документов. Следовательно, команде необходимо разработать формальный метод фиксации всех запрашиваемых изменений системы. Это может осуществляться с помощью системы отслеживания изменений и неполадок, которая обеспечивает создание централизованного архива запросов, автоматическое отслеживание состояния, автоматическую отметку затрагиваемых частей, а также механизм передачи запросов изменений в систему управления требованиями, если это необходимо.
Эту систему следует использовать, чтобы фиксировать все предложения и передавать их руководству совета по контролю над изменениями (ССВ) для принятия решения. Совет играет ключевую роль в успехе проекта. Он должен состоять из трех-пяти человек, представляющих интересы основных участников проекта: заказчиков, представителей маркетинга и руководства проекта.
Когда решается вопрос, принять ли запрос об изменении, ССВ должен учитывать следующие факторы:
влияние изменения на стоимость и функциональные возможности системы;
воздействие изменения на заказчиков и внешних участников, не представленных в ССВ (других подрядчиков проекта, поставщиков компонентов и т.д.);
возможность того, что изменение дестабилизирует систему;
при принятии решения ССВ также несет ответственность за то, чтобы отметить все, на что повлияет изменение, даже если оно не принимается;
после принятия изменения необходимо решить, куда поместить (например, нужно определить, предлагается ли изменить требование или тест).
Шаг 5. Иерархическое управление изменениями.
Если изменения тщательным образом не обрабатывать, это может привести к неприятным последствиям. Изменение одного требования может оказать возмущающее воздействие на связанные с ним требования, проектирование или другие подсистемы.
К тому же проблема осложняется тем, что при отсутствии явно заданного процесса изменения обычно производятся «восходящим» образом. Это означает, что если изменение появляется во время написания кода новой системы, оно, как правило, вносится непосредственно в программный код. В результате чего возникают вопросы: «Не вызовут ли изменения, которые вносимые в код, изменений в проекте? Повлияют ли изменения на уровне проектирования на требования? Окажут ли изменения требований к программе воздействие на документ-концепцию?»
Чтобы ослабить возмущающий эффект изменений требований, необходимо выполнять их в иерархии нисходящим образом. Если воспользоваться поддержкой автоматических средств, нисходящее распространение возмущения будет отражено механизмом трассировки, который используется при построении пирамиды требований. Это позволит работать с пирамидой сверху вниз, внося дальнейшие изменения там, где необходимо. Каждое последующее изменение обнаруживает дополнительные «подозрительные связи» или точки нижнего уровня пирамиды, где необходимо провести дополнительный анализ.
Таким образом, изменение распространяется по иерархии логичным и контролируемым образом.
Управление конфигурацией требований
Процесс рассмотрения и принятия изменений носит название «контроль изменений», «контроль версий», или управление конфигурацией (configuration management, CM).
При наличии современных инструментальных сред достаточно несложно контролировать все элементы иерархии требований посредством управления конфигурацией.
Преимущества основанного на СМ процесса управления требованиями, кратко, заключается в следующем:
предотвращаются недозволенные и потенциально деструктивные изменения требований;
предотвращаются исправления документов требований;
упрощается получение и/или восстановление предыдущих версий документов;
осуществляется поддержка реализационной стратегии, основанной на задании базового уровня и инкрементных улучшениях и обновлениях системы;
предотвращается одновременное обновление документов (т.е. нескоординированное обновление различных документов в одно и то же время).
Практический подход к управлению изменениями, предполагает наличие набора автоматических средств управления конфи- гурацией.
После задания отношений трассировки трассировочные связи можно использовать для управления изменениями.
По мере развития проекта неизбежно будут предлагаться изменения различных его элементов: от высокоуровневого документа-концепции до спецификации, реализации и тестов. Повсюду при возникновении изменения следует использовать «подозрительные связи», чтобы отметить отношения, на которые могло повлиять данное изменение. Действия по управлению изменениями обычно заключаются в одном из следующих двух шагов.
1. Если изменение функции не влияет на требование, необходимо только очистить «подозрительную связь». Заметим, что если позднее данная функция вновь будет меняться, связь снова будет отмечена как подозрительная.
2. Если функция действительно влияет на требование, может понадобиться переделать подвергшийся воздействию элемент.
Контрольный журнал изменений
В нем фиксируются изменения отдельных требований. При поддержке вспомогательной программы это позволит работать с каждым требованием отдельно, независимо от того, частью какого документа или модели оно является. Все изменения требования автоматически фиксируются (образуя историю изменений данного требования), и их можно впоследствии проверять и пересматривать.
В истории изменений указывается текущая формулировка требования, в том числе текущие значения всех его атрибутов, в хронологическом порядке представлена последовательность всех предшествующих изменений данного требования и его атрибутов. Вспомогательная программа должна автоматически фиксировать все изменения формулировки требования, а также значений его атрибутов.
Как только программа обнаруживает изменение, она автоматически фиксирует его. Кроме того, автоматически записывается автор, дата и время изменения.
История изменений организована в обратном хронологическом порядке и содержит записи изменений, как текста, так и значений отдельных атрибутов.
Таким образом, необходим набор вспомогательных средств, обеспечивающих полностью автоматическую всеобъемлющую и естественную интеграцию со стандартными приложениями, которые будут помогать в решении задач управления конфигурацией, возникающих при выполнении крупных проектов разработки программного обеспечения.
В заключение можно отметить, что спроектировать и реализовать правильную систему достаточно сложно. Один из методов состоит в том, чтобы использовать требования и прецеденты для создания архитектуры и проекта реализации.
Следует применять верификацию, аналитический подход, который позволяет постоянно отслеживать эволюцию функций, требований, проекта и реализации системы. Поддержка верификации осуществляется с помощью методов трассировки, которые позволяют связать друг с другом части проекта.
Методы трассировки позволяют убедиться, что все необходимое в проекте присутствует и учитывается. С их помощью можно также исключить ненужные элементы.
Еще одной составной частью подхода, призванного подтвердить корректность создаваемой системы, является проверка правильности (validation).
В данном случае выполняются действия по тестированию и применяются методы трассировки, чтобы убедиться, что система соответствует предъявляемым к ней требованиям.
Затем проводятся приемосдаточные испытания, призванные продемонстрировать, что в среде заказчика система работает так, как нужно, и действительно решает поставленную проблему.
Чтобы решить, какая часть системы нуждается в верификации и проверке правильности и в каком объеме, производится оценка и анализ рисков. Затраты на эти действия следует контролировать с помощью анализа дивидендов (ROI).
Наконец, критически важным аспектом построения правильной системы является процесс управления изменениями. Управление изменениями дает уверенность в том, что создаваемая система является правильной и, более того, будет правильной и в дальнейшем.