Без подходящих программистских приемов: алгоритмов, структур данных, контрактов, анализа производительности, модульной структуры, поддержки компилятора, поддержки инструментария и других изученных приемов — без всего этого проекты потерпят неудачу. Необходима технология, но ее недостаточно. Успешные системы строятся в интересах клиентов и должны соответствовать их потребностям. Анализ требований позволяет достигнуть хорошего соответствия между тем, что хотят пользователи, и тем, что делает система.
В этом одна из центральных задач разработки. Она трудна, но может доставлять радость. Самое время развеять взгляд на программистов как на погруженных в себя зануд. На самом деле практика показывает, что они много времени проводят в обсуждениях с пользователями и другими нетехническими участниками.
Следующий обзор описывает некоторые из вызовов, с которыми приходится сталкиваться, и несколько принципов, которые следует учитывать при разработке эффективных требований.
Процесс создания требований должен выдавать два конкретных результата:
Второй продукт часто игнорируется, но он так же важен, как и первый. Пришло время серьезных проектов, когда перед построением ПО создается хороший ВП-план, а еще лучше — хороший страховочный план. Создание тестов на этом этапе направлено на оценку соответствия системы заявленным намерениям. Чем позднее создаются тесты, тем вероятнее, что они будут руководствоваться решениями, принятыми на этапе проектирования и реализации, и в меньшей степени — потребностями клиентов.
Существует полезный ресурс для подготовки требований: стандарт IEEE
Это краткий и простой стандарт. С ним стоит познакомиться, а если необходимо написать требования — то следовать рекомендуемой структуре, широко используемой в индустрии. Эта структура состоит из трех частей: введения, общего описания и специфических требований. Часть 2, помимо описания, включает перспективу продукта, функции продукта, характеристики пользователя, ограничения, предположения, зависимости, выделенные требования. Часть 3 идет глубже, уделяет внимание таким деталям системы, как внешние интерфейсы, требования к производительности, требования к базам данных.
Все это — не более чем контрольный список свойств системы, указываемый в требованиях. Поскольку многие из этих свойств могут влиять на успех разработки, следующий стандарт помогает авансом избежать дорогостоящих ошибок.
Программная система почти всегда является частью большой системы. Встроенное ПО, скажем, в цифровую камеру или мобильный телефон, является частью системы, включающей аппаратуру. Бизнес-ПО — это часть системы, включающей процессы компании. Одно из первых решений, которое приходится принимать при подготовке требований, — должны ли они относиться только к ПО или ко всей системе. Первый ответ не означает игнорирование системы, он предполагает, что будут заданы четкие интерфейсы между ПО и его окружением.
Еще одно важное разграничение, отмеченное ранее, — разграничение функциональных и не функциональных аспектов.
Обратите внимание на терминологию: "требование" — это элемент специфицируемого поведения, функционально или нефункционального, как в приведенных примерах. Требования — это коллекция таких индивидуальных элементов.
Процесс получения (или
Этот последний комментарий проясняет общее свойство сбора требований. Вы, возможно, полагаете, что в идеале процесс полностью создается на основе "потребностей пользователей": некоторая команда внимательно опрашивает клиентов, выясняя, что они хотят, записывает их ответы, сортирует, создает документ требований и вручает его команде разработчиков, которая и реализует желания клиентов. Так почти никогда не происходит. Так и не должно происходить.
Наблюдения показывают, что помимо простейшего случая сбора пожеланий клиентов и их последующей реализации, обычный процесс — итеративный: пользователи высказывают пожелания, разработчики предлагают легко реализуемые свойства и после нескольких итераций останавливаются где-то посередине. Такие обсуждения могут носить креативный характер, в результате могут появиться требования, которые ранее ни одна из групп и не предполагала.
Процесс принятия требований должен поддерживать эту модель. Практическое правило состоит в том, что разработка не должна начинаться до одобрения документа требований. Он должен быть подписан заказчиком с правом ответственной подписи и руководителем группы разработки. Многих ошибок в проектах можно было бы избежать, придерживаясь этого простого правила.
Иногда компания создает документ требований, не имея команды разработчиков, внешней или внутренней, так что описанный процесс становится неприменимым. Идея в таких случаях понятна - вначале определить требования, а потом выбрать команду, наилучшим образом реализующую требования. Это рискованная практика. Она может приводить к нереализуемым требованиям. Риск особенно возрастает, если на этом этапе привлекать внешних консультантов для проведения анализа требований. Мне неоднократно доводилось видеть для индустриальных проектов, что такой процесс приводит к завышенным требованиям. Слишком велико желание сделать приятное заказчикам, давая обещание, выполнять которое должен кто-то другой. В таких ситуациях в лучшем случае требования будут неизбежно пересмотрены, в худшем - реализация приведет к задержкам или неудаче.
Приемы для сбора требований включают:
интервью. Представители разных категорий сопричастников опрашиваются с целью выяснения, что они ждут от новой системы или от изменения существующей. Интервью должны быть тщательно подготовлены, включать вопросы по отдельным разделам и иметь открытую часть для пожеланий в свободной форме. Общей практикой является видеозапись интервью, чтобы к нему можно было бы возвращаться при необходимости;
семинары. Сбор в одном месте опрашиваемых людей может быть лучше, чем индивидуальные интервью. В этом случае часто на месте удается устранить разногласия, возникающие у разных групп сопричастников;
предыдущие системы. Редко, когда система начинается на пустом месте. Обычно уже существует система, отвечающая тем же потребностям. Изучение существующих систем, их достоинств и недостатков, является важной частью сбора требований. Одним из технических требований в таких ситуация может быть требование, чтобы новая система, по меньшей мере, работала не хуже старой и давала те же результаты в сравнимых случаях;
конкурирующие системы. Необходимо знать, что предлагают конкуренты. Даже если речь идет о внутренней разработке, полезно знать, как справляются с этим конкуренты, имеющие те же потребности.
Одним из продуктов, входящим в состав требований, должен быть глоссарий (в стандарте IEEE это раздел 1.3 "Определения, акронимы, аббревиатуры").
Каждая проблемная область имеет свой жаргон. Эксперты в этой области используют его в интервью и семинарах, предполагая, что интервьюер понимает его и что остальные эксперты понимают его так же, как и они. Оба предположения могут оказаться неверными. Первой задачей документа требования является перечисление употребляемых терминов и определение их точного технического смысла. Соберите все такие определения в глоссарий, покажите его экспертам, чтобы убедиться, что они согласны с вами и друг с другом. Глоссарий является одним из принципиальных ресурсов для процесса разработки требований. Но он используется не только для этих целей, поскольку многие концепции, перечисленные в глоссарии, будут необходим прямым двойникам (классам, компонентам) в программах.
При написании требований всегда следует четко разграничивать машинные и проблемные свойства (о чем убедительно сказано в книге Майкла Джексона, см. ссылку в конце лекции).
(рис 10.1) Майкл Джексон (2004)
Любая система функционирует в некоторой проблемной области со своими законами: в электронике действуют физические ограничения на скорость сигнала, в банковской сфере — своя система правил. Программная система, появляющаяся в результате разработки, может рассматриваться, как уже говорилось, как своего рода машина со своими законами. Джексон указывает на необходимость разграничений двух категорий требований.
В кратком тексте, описывающем Парижское метро, утверждение "У метро есть важное свойство — всегда существует маршрут для любой пары станций метро (математики бы сказали, что метро задается связным графом)" — является проблемным свойством. Любая программная система, связанная с метро, должна гарантировать выполнение этого свойства. Правило, нумерующее станции с юга на север (явно введенное "для упрощения жизни"), является машинным правилом, которое описывает частное соглашение, выбранное в конкретной модели метро.
Помимо необходимости понимания проблемной области возникает еще одна новая задача, отличающаяся от инженерии требований, — инженерия проблемной области, направленная на моделирование общих свойств проблемной области. Инженерия проблемной области не связана с конкретным проектом, но помогает процессу задания требований для всех проектов данной проблемной области. Например, компания, которая регулярно разрабатывает проекты, связанные с управлением движения поездов, может инвестировать средства в моделирование общих свойств железнодорожных систем.
Требования являются комбинацией машинных и проблемных ограничений. Слишком часто документы требований не разграничивают эти два вида требований. В результате читатели документа, в частности, разработчики, не понимают четко, что является следствием внешних обстоятельств (скорость света изменить нельзя), а что может быть пересмотрено при эволюции системы. По этой причине важно в документе требований специфицировать их природу — машинную или проблемную — для каждого частного требования.
Давайте дополним наш обзор рассмотрением свойств — пятнадцати свойств, — которым должны удовлетворять хорошие требования. Рассмотрим требования к требованиям. Должен заметить, что я никогда не видел документ, удовлетворяющий всем этим свойствам, но они обеспечивают ясное понимание принципов, которым должен следовать каждый разработчик требований. Некоторые, но не все, отвечают стандарту IEEE, ниже они отмечены звездочкой.
Требования должны быть обоснованными. Каждое индивидуальное требование должно иметь источником идентифицируемую и явно установленную потребность сопричастника.
Требования должны быть корректными *. Любая система, удовлетворяющая требованиям, должна отвечать потребностям сопричастников. Формально это невозможно гарантировать. Неформально нужно быть уверенными, что все сопричастники знакомы с требованиями и согласны с относящимися к ним требованиями.
Требования должны быть полными. Они должны покрывать все потребности сопричастников. В принципе, полнота не проверяема, так как возникает естественный вопрос — полнота по отношению к чему? Любой ответ будет ссылаться на некий более высокий уровень, новый документ, куда и переносится решение проблемы. На практике существуют полезные эвристики, основанные на концепциях, введенных ранее в этой книге.
Подобно классу, каждая система обеспечивает команды и запросы. Можно выполнять некоторые действия и можно запрашивать информацию. Документ требований должен описывать как команды, так и запросы. Информации должно быть достаточно, чтобы читатель требований мог определить, как выполнение любой команды будет воздействовать на любой из доступных запросов.
"Достаточная полнота" - технический термин, введенный в 1978 году в статье Гутта-га и Хорнинга для характеристики свойств абстрактных типов данных, теоретической основы ОО-программирования.
Требования должны быть согласованными. Они не должны включать противоречий. Этого на удивление трудно достигнуть. Трудность частично связана с размером многих индустриальных документов требований, которые могут составлять сотни и тысячи страниц для сложных систем. Несогласованности прокрадываются в документ. На странице 235 утверждается, что шлагбаум должен опускаться до звукового сигнала, свидетельствующего о приближении поезда, а на странице 1232 утверждается обратное. Программисту нужно выбрать что-то одно. На этапе принятия требований несогласованности должны быть обнаружены и устранены.
Заметьте разницу между согласованностью и корректностью: согласованность - внутреннее свойство документа требований, корректность указывает на удовлетворение некоторым
Требования должны быть недвусмысленными. Задача трудновыполнимая, поскольку документы требований пишутся на естественном языке с присущей ему неоднозначностью. Рассмотрим пример:
Фоновый менеджер задач должен обеспечивать сообщения о статусе с регулярными интервалами, не превышающими 60 секунд.
Пример взят из "SoftwareRequirements", см. ссылку в пункте "Дальнейшее чтение".
Разработчики системы по-разному могут истолковать это требование, некоторые интерпретации могут не устраивать пользователей. Эксперт по требованиям, процитировавший этот фрагмент, предложил в качестве замены некоторые варианты (сделав некоторые предположения о намерениях, которые можно было бы проверить у пользователей).
Это значительно более точный и типичный стиль для индустриальных требований. Пример является хорошей иллюстрацией тех трудностей, которые возникают при задании требований, он позволяет понять, почему тщательно написанный документ требований может занимать тысячи страниц.
Естественные языки не способствуют точности описаний. По этой причине во многих работах предпринимаются значительные усилия по использованию математических приемов для задания требований, называемых в этом случае формальными спецификациями.
Статья о "Формализме в спецификациях", см. ссылку в конце лекции в разделе "Дальнейшее чтение", обсуждает преимущества и недостатки такого подхода.
Требования должны быть осуществимыми. Вполне возможно "витание в облаках" при задании требований, особенно, как отмечалось, если требования пишут не те, кто будет их реализовать. Серьезный процесс включает ограничение амбиций и понимание возможностей.
Требования должны быть абстрактными. Типичный просчет при подготовке требований состоит в попытках задания решений, которые следует принимать на последующих этапах проектирования и реализации. Такая сверхспецификация сужает возможности и не соответствует миссии требований, которые должны говорить, что нужно делать, но не определять, как делать.
Требования должны быть прослеживамыми*. Другими словами, должна быть возможность проследить в коде и в других программных продуктах все последствия каждого индивидуального требования. Это позволяет не только проверить, чтобы предлагаемая реализация удовлетворяла всем требованиям, но и при изменении требования проследить за всеми программными элементами, затронутыми этим изменением.
Примером механизма прослеживания в EiffelStudio является средство, названное
Требования должны быть верифицируемыми*. Бесполезно задавать требование, если нет способа проверки его выполнения в программной системе. Экстремальным — но, к несчастью, распространённым — примером неверифицируемого требования является требование в форме "система должна работать в реальном времени, выполняя команды и запросы". Но что такое "реальное время", может оставаться загадкой. Для банковской системы ответ на запрос в течение 2-х секунд — это реальное время, для сетевых устройств реальным временем может быть 100 микросекунд. Документ должен указывать точные значения, задавая среднее значение и допустимые отклонения.
Требования должны быть ограничительными. Важно установить не только то, что система должна делать, но и то, что лежит за пределами ее компетенции.
Требования должны задавать интерфейс. Следует точно установить связи системы с внешним миром — людьми, аппаратурой, другими программными системами.
Требования должны быть приоритетными*. Иногда обстоятельства заставляют отказаться в проекте от полной реализации всего, что было запланировано. Типичной причиной отказа является урезание бюджета.
Причиной могут стать неожиданно возникшие трудности, приводящие к задержке проекта, и, как следствие, ограничение функциональности, чтобы проект мог выйти в запланированные сроки. Иногда приходится форсировать выпуск, чтобы опередить конкурирующий продукт. Выбор того, чем следует пожертвовать, не должен приниматься спонтанно. Требования должны устанавливать важность каждой функциональности, это позволяет делать выбор на основе предварительно согласованных приоритетов.
Требования должны быть понятными. Стремление к точности и детализации может в результате дать обратный эффект, приводя к громоздким документам. Если требования не будут просты для понимания, они не сыграют свою роль.
Требования должны быть модифицируемыми*. Меняются обстоятельства, меняется сознание людей, компании могут сливаться. Подобно любым другим программным продуктам, требования должны проектироваться с учетом возможных изменений.
Ну и, наконец, требования должны быть одобрены и подписаны. Так много места для непонимания и конфликтов, что не следует начинать разработку проекта без ясного формального понимания, включающего, по крайней мере, подписи людей, ответственных за проект с двух сторон — со стороны заказчика и со стороны команды разработчиков.
Надеюсь, я не напугал вас этим длинным списком критериев хороших требований. Документ хороших, хотя и не совершенных требований написать вполне возможно, он будет отображать потребности сопричастников проекта и будет служить основой для разработки и ВП-реализации. Это важная часть разработки ПО и великолепная возможность комбинировать технологию с бизнесом, учитывая при этом психологию людей.
Первое правило ВП говорит, что было бы прекрасно, если бы этого не нужно было делать. Цель всех правил проектирования и методологии программирования, изучаемых в этой книге (а я верю, что вы будете применять каждое из них при каждом подходящем случае), состоит в том, чтобы создавать программный продукт, который будет работать с первого раза и каждый раз. Но все же нужно убедить в этом остальной мир, не исключая возможности, что ошибки могут встретиться и в вашей работе. Кроме того, иногда ведь приходится модифицировать продукт, написанный другим, менее просвещенным программистом. На практике ВП является главной частью усилий при разработке проекта, часто занимающей больше времени, чем само конструирование ПО.
Ограничим себя обзором некоторых базисных идей. Обсуждение главным образом коснется программ, хотя, как отмечалось, ВП применима и к непрограммным артефактам, таким как документация. Термин "страхование качества ПО" будет использоваться как синоним ВП.
Это некоторое насилие над языком, так как страхование качества включает методы построения качественного ПО и методы оценивания качества построенного ПО.
Многие люди под ВП понимают только тестирование и отладку. Фактически, область применения методов ВП значительно шире. Тестирование — главный вид динамических методов — заключается в выполнении системы (поэтому и динамический метод) на выбранных входах. Цель тестирования — обнаружение дефектов.
Статические методы анализируют текст программы без ее выполнения. Они включают осмотр кода, его статический анализ, доказательство корректности, проверку на соответствие модели.
Наше рассмотрение начнем с тестирования, а затем перейдём к статическим приемам. Следующие термины, полезные при обсуждении, идут от еще одного IEEE-стандарта по терминологии инженерии программ.
IEEEStd 610.12-1990, tinyurl.com/3w57pk (текст 1990 года, но во многом все еще полезен).
Выполнение программы, не функционирующее, как ожидалось (дает неверные результаты или приводит к аварийному завершению), называется отказом (failure).
Отказ (за исключением редких случаев отказа аппаратуры) — следствие дефекта (fault) ПО, свидетельствующее, что ПО работает не так, как должно. Заметьте, что дефект не обязательно является ошибкой реализации, он может возникать из-за ошибок на любом уровне, таких как спецификация или проектирование.
Дефект является следствием ошибки (mistake), сделанной разработчиком ПО. Термин "баг", или "жучок", не является частью официальной терминологии, хотя часто
используется для обозначения дефектов или ошибок чаще всего при отладке — задаче исправления ошибок, удаления дефектов и устранения отказов.
Начнем с тестирования — наиболее применяемой программистами техники. Первое наблюдение свидетельствует о скромной роли тестирования, поскольку оно не дает гарантий качества. Причина была указана Эдсгером Дейкстрой, это его высказывание является одним из наиболее цитируемых в истории информатики: "Тестирование может показать наличие ошибок, но не их отсутствие".
Ошибочный тест выявляет дефект, успешный тест мало о чем говорит, так как в любой реальной программе число тестов невероятно велико. Даже программа, которая умножает два числа из 64-х битов, имеет 2128 вариантов.
Комментарий Дейкстры справедлив, но он не свидетельствует о грехах тестирования. "Показать наличие ошибок" — дело, чрезвычайно полезное для практики, позволяющее нам найти ошибки до того, как их найдут пользователи. Тестирование — это техника обнаружения ошибок.
За последние годы технология тестирования существенно прогрессировала. Эволюция шла в направлении большей автоматизации. Для всех известных языков программирования появились специальные инструментальные средства — каркасы, позволяющие записывать тесты и автоматически запускать систему тестов. Эти средства известны под общим именем "XUnit", следуя названию JUnit — каркасу Java. Их широкий успех объясняется тем, что альтернативный способ — ручное управление и выполнение тестов — стал нереалистичным для современных программ, требующих запуска большого числа тестов. Мощь компьютеров сделала возможным проверку системы на многих тестах, но для этого требуется автоматическая поддержка.
Автоматизация, в частности, необходима для задачи, известной как регрессионное тестирование. Имеет место факт, удивительный для новичков, но характерный для разработки ПО,— исправленные дефекты могут вновь появляться в последующих релизах (ПО частично регрессирует к прежнему состоянию, отсюда и название — регрессионное тестирование). Причины регрессии следующие:
Регрессионное тестирование пытается захватить все такие случаи, выполняя все тесты, на которых возникала ошибка. Каждый серьезный проект выполняет регрессионное тестирование при каждом новом выпуске системы. Это отражается в следующем принципе.
Современные исследования автоматизации тестирования идут значительно дальше. Примером новых возможностей является каркас — EiffelTestFramework, который, начиная с версии 6.3, стал интегральной частью EiffelStudio. Здесь в добавление к стандартному механизму "XUnit" появились два продвинутых свойства.
Тестирование — активно развивающаяся область исследований, так что можно ожидать появления новых инструментариев и новых возможностей в будущих средах разработки.
Возвращаясь назад, к сегодняшней технологии тестирования, стоит рассмотреть несколько новых понятий (за деталями следует обратиться к учебникам по инженерии программ и литературе по тестированию).
Тестирование встречается на разных уровнях гранулярности.
Юнит-тестирование (модульное тестирование) предназначено для тестирования отдельных модулей — типично классов или кластеров в ОО-разработке. Обычно оно выполняется индивидуальными разработчиками соответствующих модулей.
Интеграционное тестирование оценивает, как выполняется группа модулей или подсистем при их соединении. Обычно это задача группы разработчиков, возможно, выполняемая специализированным подмножеством — командой тестеров или командой страхования качества.
Системное тестирование тестирует систему в целом. Часто этот шаг по-прежнему выполняется командой тестеров. Приемочное тестирование предполагает тестирование с позиций заказчика, и ответственность за него лежит на организации заказчика, оно выполняется объединенной группой представителей разработчиков и заказчика.
Для юнит-тестирования принято различать два подхода — черный и белый ящики. При тестировании белого ящика доступен текст программы, позволяющий руководить процессом тестирования, в то время как тестирование черного ящика целиком основано на
В заключение отметим концепцию покрытия тестов, применимую главным образом к белым ящикам. Покрытие — это мера качества набора тестов, позволяющая оценить объем протестированной функциональности. Меры покрытия могут включать:
Существует много других критериев покрытия, хотя в конечном итоге считать нужно было бы, каков процент обнаруженных ошибок дает данный набор тестов. Этот критерий может коррелировать или не коррелировать с элементарными мерами покрытия. Обобщение черного ящика приводит к понятию покрытия спецификации, дающего оценку, как много случаев, допускаемых спецификацией, были испытаны.
Закончим обзор ВП рассмотрением статических методов.
Обзор проекта и кода, называемый также инспекцией, является процессом, выполняемым вручную для обнаружения дефектов и других неисправностей. Целью инспекции типично бывает программный элемент, за разработку которого отвечает один исполнитель. Таким элементом может быть класс, но может быть и глава из руководства пользователя. Текст пускается по кругу, а затем обсуждается на встрече в интересах обнаружения возможных проблем. Встреча не имеет других целей — не оценивается сам разработчик и не предполагается исправление обнаруженных проблем (эту задачу будет решать разработчик самостоятельно после встречи).
Это описание классической идеи обзора кода. С наступлением эры Интернета и все большим распространением географически распределенных команд разработчиков этот процесс может использовать возможности удаленного доступа и видеоконференций. Один из уроков такого опыта состоит в том, что обзор становится более эффективным, если частично сопровождается написанием замечаний. Процесс начинается еще до встречи, когда участники аннотируют общий документ (технология разделения Web-документов теперь широко доступна). По большинству замечаний на этом этапе разработчик и его критики приходят к согласию. На встречу (видеоконференцию) выносятся вопросы, требующие дополнительного обсуждения.
Моя статья "Design and Code Reviews in the Age of the Internet" (Communications of the ACM, vol. 51, no. 9, September 2008) описывает этот процесс в деталях.
Нельзя ожидать, что инспекция кода является эффективным инструментом для систематического обнаружения дефектов. Обзор кода является процессом, требующим больших затрат времени разработчиков — самого дорогого ресурса. Хорошей идей является применение этого подхода для критически важных модулей. Главная же цель выполнения обзоров состоит в оценке общих практик проектирования и кодирования, применяемых в команде, особенно практик, способных повредить качеству системы. Крайне важно, когда обзор выявил недостатки, выявить их причины и понять, какие же методы могут быть использованы, чтобы избежать подобных ошибок в будущем.
Более эффективный процесс статического анализа требует автоматизированного инструментария. Компилятор статически типизированного языка включает статический анализатор, являющийся частью компилятора и обеспечивающий безопасность системы типов. Помимо прямой реализации правил языка программирования статический анализатор ищет образцы кода, которые могут приводить к ошибкам, даже если они явно не нарушают правила языка. Примеры включают:
Специальной формой статического анализа является доказательство корректности программ — наиболее амбициозный и наиболее трудный подход. Термин "доказательство" используется в математическом смысле и, следовательно, предполагает некий формализм при задании спецификаций. Контракты Eiffel дают представление о том, как может выглядеть такой формализм: каждый программный элемент характеризуется предусловием и постусловием (для методов) или инвариантом (для класса). Это абстрактные спецификации функциональности. Для полного доказательства спецификации должны быть детализированы, но общая идея остается применимой. "Доказательство" класса тогда означает установление математическими методами, что реализация удовлетворяет спецификации: каждый метод, запущенный в состоянии, удовлетворяющем инварианту и предусловию, будет завершать свое выполнение в состоянии, удовлетворяющем постусловию и инварианту.
Эта форма спецификаций согласована с наблюдением, приведенным ранее в этой лекции, что корректность программы может быть определена только по отношению к заданной спецификации. Здесь спецификации принимают форму контрактов, а корректность означает, что реализация согласована с контрактами.
Поскольку такие доказательства требуют включения многих деталей, а также и потому, что доказательствам, сделанным человеком, нельзя полностью доверять (ошибки в доказательствах возможны не в меньшей степени, чем ошибки в программе), процесс должен основываться на автоматически работающем инструментарии, выполняющем доказательство корректности программ. Многие такие программы представляют надстройку над программами, доказывающими правильность теорем, способных выполнять математические выводы. Работы над автоматизацией методов доказательства ведутся десятилетиями; в последние годы они получили новые импульсы благодаря продвижениям в технологии доказательств и лучшего понимания проблем. Это активно развиваемая область исследований.
Наиболее впечатляющий прогресс достигнут в направлении, где обычно не пытаются дать полное доказательство корректности, но фокусируются вместо этого на идентификации специфических отказов, — то, что обычно делает тестирование.
Что это дает, можете вы спросить, для повседневной практики программирования? Это во многом зависит от места вашей работы. Долгое время формальные методы — доказательства и связанные приемы — рассматривались как интеллектуально привлекательные идеи, не применимые в индустриальных разработках (назвать подход "академическим" равносильно "поцелую смерти"). Эта точка зрения сегодня уже не доминирует. При постоянном улучшении как теории, так и инструментария, и с возрастающей опасностью рисков неверно функционирующих программных систем растет число индустриальных разработок, использующих формальные методы и инструменты. Некоторые из уроков обнадеживают, некоторые разочаровывают.
Все эти свойства современной технологии облегчают конструирование больших программ с элегантной архитектурой, открытой для расширения и повторного использования, предоставляя программистам выразительную мощь языка программирования. В результате формальные методы пока применяются в той области, где существует один критерий — корректность. Сюда относятся жизненно важные системы, такие как системы управления самолетами или поездами, где должно быть сделано все, чтобы избежать ошибок функционирования. Пример ПО "Аэробуса" является показательным.
Остальная часть индустрии обычно не готова принять такой вид аскетизма, который требует техника доказательств от своих последователей. Ведутся серьезные исследования, чтобы сделать их более применимыми в главных направлениях разработки ПО. Тони Хо-ар выступил с инициативой "
Наша последняя тема этой лекция посвящена общему организационному подходу, который применяется в компаниях последние годы. Он соответствует духу идей моделей жизненного цикла, обсуждаемых ранее в этой лекции, но расширяет их рамки.
Предположим, что вашей организации необходимо заключить контракт на разработку ПО с некоторой программистской компанией. Пока нет продукта, который можно было бы оценить, так что оценке может подлежать только сам процесс разработки. Компания убеждает вас, что у нее все находится под контролем, но как это проверить?
В начале 90-х годов необходимость объективной оценки программистских фирм возникла у Министерства обороны Соединенных Штатов — крупнейшего заказчика ПО для своих нужд. Для решения этой задачи Институту программной инженерии Университета Карнеги-Меллона был сделан заказ на разработку модели, определяющей уровень зрелости программистских фирм. Разработанная ими модель получила название "Capability Maturity Model" (акроним CMM), а позже модель была расширена и стала называться CMMI-моделью — "интеграционная модель зрелости и способностей". Эта модель оказала существенное влияние на некоторые сегменты рынка ПО, в частности:
Модель CMMI используется и вне этих сообществ. Доля организаций, работающих с оборонными заказами и сертифицированных по CMMI, неуклонно сокращается, в 2004 году она составляла
Некоторые компании в поисках процесса улучшения организации работ и квалификации предпочитают другие модели. Серия стандартов 9000 ISO также устанавливает международные стандарты качества. Стандарт SPIQE комбинирует элементы предыдущих двух стандартов. В этом обзоре рассматривается только CMMI.
CMMI и другие модели исследуют только процессы. Они нейтральны к используемым технологиям, языкам и инструментарию. Все они оценивают, имеет ли организация набор четких процедур для каждого рода деятельности, применяются ли эти процедуры, контролируется ли их применение, измеряется ли эффект, прилагаются ли усилия по их улучшению. Вспоминая предыдущее наше обсуждение о качестве ПО, скажем, что модели следят за факторами процесса, особенно за последними пятью из нашего списка.
Процесс сертификации аналогичен проверке пилотом самолета перед вылетом
Из-за акцента на формальные процедуры в ущерб технологиям ряд специалистов критически относятся к моделям процессов, полагая, что они главным образом служат интересам менеджеров проекта, подкладывающих соломку на случай неуспеха проекта, — они делали все по инструкции. И в самом деле, известны случаи провала проектов в организациях с высоким уровнем сертификации CMMI или ISO. Но это классический пример, когда выполняется необходимое, но не достаточное условие. Программным проектам, особенно большим, необходимо высокое качество процессов, но этого недостаточно, им для успеха необходима также и выдающаяся технология.
Ключевым в CMMI является понятие оценивания. Организации, желающие установить свой уровень зрелости, могут сделать это, обратившись к официальным оценщикам, аккредитованным в Институте программной инженерии. В 2005 году Институт аккредитовал 179 оценщиков, главным образом организации, занимающиеся такого рода деятельностью. Организации, получившие сертификат об уровне их зрелости, могут опубликовать его и использовать в рекламных целях для повышения своей привлекательности.
Как указывает буква "I" в акрониме (Integration), CMMI пошла дальше CMM для того, чтобы расширить сферу воздействия на модели, отличные от программных. Четыре дисциплины кроме инженерии программ включают также:
Организации, реализующие CMMI и желающие получить сертификат, могут выбирать любую из этих дисциплин в зависимости от их деятельности и потребностей.
Основа CMMI — определение целей и рекомендуемых практик.
Как показывают примеры, каждая практика должна быть связана с некоторой целью. Если использовать программистскую технологию, то цель — это спецификация, а практика — ее реализация (выполняемая людьми).
Цели и соответствующие им практики группируются в коллекции, называемые областью процесса. Приведенные примеры могут рассматриваться как часть области процесса "Разработка требований".
Термин "область" не является интуитивно понятным, так что просто следуйте определению — область, содержащая коллекцию целей и практик, поддерживающих эти цели.
CMMI существует в двух вариантах — ступенчатом, или поэтапном, и непрерывном.
Общим для обоих вариантов является понятие уровня оценивания. В поэтапном варианте организация получает оценку от 1 до 5 (как в школе). Чем выше оценка, тем выше уровень контроля процессов. В непрерывном варианте оценивается каждая область, здесь добавляется уровень 0, свидетельствующий о том, что организация не занимается этой конкретной областью процессов.
В поэтапном варианте каждый уровень характеризуется своим набором областей процессов. Вы достигаете соответствующего уровня, если отвечаете соответствующим целям и применяете нужные практики. Например, для достижения уровня 2 необходимо удовлетворять области процесса "Управление требованиями" и другим областям, перечисленным ниже. Кроме того, каждый уровень имеет родовую цель и связанное множество родовых практик. Для уровня 2 родовой целью является "Организация управляемого процесса", означающая, что в компании определён процесс разработки и принимаются меры по его соблюдению. Связанными родовыми практиками являются такие практики, как "Планирование процесса" и "Обеспечение ресурсами".
Как следствие этих концепций, цели и практики разделяются на две категории.
Дадим общую характеристику уровней для поэтапного варианта. Более точное определение дается ниже приводимой таблицей, которая идентифицирует в отдельности родовые и специфические цели. Как говорилось, выделяется пять уровней.
Следующая таблица более точно описывает, что должно достигаться на каждом уровне (начиная со 2-го, поскольку по определению на уровне 1 нет точных требований).
| Уровень | Имя | Области процессов |
|---|---|---|
| 2 | Управляемый | |
| 3 | Определенный | |
| 4 | Количественно управляемый | |
| 5 | Оптимизирующий |
CMMI определяет на каждом уровне точное множество целей и практик. Мы не будем заниматься этими деталями, надеясь, что вы разберетесь с ними сами, изучая литературу по CMMI, где вы сможете найти и метод, известный как персональный процесс разработки, который применяют индивидуальные разработчики, руководствуясь изложенными идеями.
Carlo Ghezzi, Mehdi Jazayeri and Dino Mandrioli: Fundamentals of Software Engineering, 2nd Edition, Prentice-Hall, 2002.
Хорошо известный учебник по инженерии программ, дающий полное представление о предмете. Другими хорошими учебниками являются: S.L. Pfleeger, J. Atlee (3rd edition, Prentice Hall, 2005) и Roger Pressman (6th edition, McGraw Hill, 2005).
(рис 10.2) Карло Чеззи (2008) Дино Мандриоли (2008)
IEEE
Доступна при условии регистрации на сайте: ieeexplore.ieee.org/xpl/tocresult.jsp?isNumber =15571
Краткий стандарт, описывающий лучшие практики написания документов требований, включая рекомендуемую структуру документа, которая широко применятся в индустрии.
Bertrand Meyer: On Formalism in Specifications, in IEEE Software, vol. 3, no. 1, January 1985, pages 6-25.
Доступна на сайте: se.ethz.ch/~meyer/publications/computer/formalism.html
Старая статья, объясняющая, почему полезно для задания спецификаций использовать математические методы.
John V. Guttag and James J. Horning: The
Конструктивная статья по теории абстрактных типов данных, лежащих в основе объектной технологии. Вводит понятие "достаточной полноты".
(рис 10.3) Джим Хорнинг (2007)
KarlE. Wiegers: SoftwareRequirements, MicrosoftPress, 2003.
Набор полезных правил для написания хороших документов требований.
Michael Jackson: Software Requirements and Specifications: A
Прекрасное обсуждение требований и спецификаций.
Axel
Еще одна прекрасная книга по требованиям, наиболее современная, от одного из авторитетов в этой области. Хорошая теория и примеры. Bertrand Meyer and Jim Woodcock (editors): VSTTE (Verified Software: Theories, Tools, Experiments),
Труды содержат работу Тони Хоара "GrandChallenge". Хорошая оценка состояния искусства
Frederick P.
На русском языке: "Мифический человеко-месяц" см., например, на сайте: http://www.webkomora.com.ua/ru/articles/web/management/man-month.html
Фред Брукс из IBM управлял разработкой OS/360, одной из первых сложных операционных систем, доступной на серии компьютеров. Эта книга, где он суммирует свой опыт в коротких эссе, должна быть упомянута, так как считается классикой в инженерии программ, она в большой степени стала народным фольклором.
(рис 10.4) Фредерик Брукс (2007)
Software Engineering Institute: Capability Maturity Model Integration (CMMI)
Обзор, доступный на сайте: http://www.sei.cmu.edu/cmmi/adoption/pdf/cmmi-overview07.pdf
Software Engineering Institute: Capability Maturity Model® Integration (CMMISM), Version 1.1, CMMISM for
Доступна на сайте: tinyurl.com/kf9uy (
Это официальное, детальное описание CMMI, поэтапного представления.
Непрерывный вариант: tinyurl.com/gjla9
(рис 10.5) Уотс Хэмпфри (2007)
Описывает персональный процесс разработки —
| Adequacy | Адекватность | Built-in assessment | Встроенное оценивание |
| Correctness | Корректность | Correctibility | Способность к изменениям |
| Cost control | Управление стоимостью | Efficiency | Эффективность |
| Extendibility | Расширяемость | Factor (of software quality) | Фактор (качества ПО) |
| Goal (CMMI) | Цель (CMMI) | Lifecycle | Жизненный цикл |
| Maintenance | Сопровождение | Measurability | Измеримость |
| Portability | Переносимость | Practice (CMMI) | Практика (CMMI) |
| Predictability | Предсказуемость | Process (vs product) | Процесс (в сравнении с продуктом) |
| Process area (CMMI) | Область процесса (CMMI) | Product (vs process) | Продукт (в сравнении с процессом) |
| Production software | Производство ПО | Reproducibility | Воспроизводимость |
| Reusability | Повторное использование | Robustness | Устойчивость |
| Security | Безопасность | Self-improvement | Самоулучшение |
| Software engineering | Инженерия программ | Stakeholder | Сопричастник |
Дайте точное определение терминам словаря.
Могут ли сопричастники программного проекта быть соперниками? Обсудите, в какой части они или концепции о них могут играть роль в построении ПО и управлении проектом.
В обзоре CMMI, указанном в разделе "Дальнейшее чтение", приводится высказывание (и его критика) неназванного старшего менеджера: "Я бы предпочел вовремя выпустить проект с ошибками, чем опоздать с выпуском. Позже мы всегда сможем исправить ошибки". Обсудите это высказывание с позиций инженерии программ.
Без подходящих программистских приемов: алгоритмов, структур данных, контрактов, анализа производительности, модульной структуры, поддержки компилятора, поддержки инструментария и других изученных приемов — без всего этого проекты потерпят неудачу. Необходима технология, но ее недостаточно. Успешные системы строятся в интересах клиентов и должны соответствовать их потребностям. Анализ требований позволяет достигнуть хорошего соответствия между тем, что хотят пользователи, и тем, что делает система.
В этом одна из центральных задач разработки. Она трудна, но может доставлять радость. Самое время развеять взгляд на программистов как на погруженных в себя зануд. На самом деле практика показывает, что они много времени проводят в обсуждениях с пользователями и другими нетехническими участниками.
Следующий обзор описывает некоторые из вызовов, с которыми приходится сталкиваться, и несколько принципов, которые следует учитывать при разработке эффективных требований.
Процесс создания требований должен выдавать два конкретных результата:
Второй продукт часто игнорируется, но он так же важен, как и первый. Пришло время серьезных проектов, когда перед построением ПО создается хороший ВП-план, а еще лучше — хороший страховочный план. Создание тестов на этом этапе направлено на оценку соответствия системы заявленным намерениям. Чем позднее создаются тесты, тем вероятнее, что они будут руководствоваться решениями, принятыми на этапе проектирования и реализации, и в меньшей степени — потребностями клиентов.
Существует полезный ресурс для подготовки требований: стандарт IEEE
Это краткий и простой стандарт. С ним стоит познакомиться, а если необходимо написать требования — то следовать рекомендуемой структуре, широко используемой в индустрии. Эта структура состоит из трех частей: введения, общего описания и специфических требований. Часть 2, помимо описания, включает перспективу продукта, функции продукта, характеристики пользователя, ограничения, предположения, зависимости, выделенные требования. Часть 3 идет глубже, уделяет внимание таким деталям системы, как внешние интерфейсы, требования к производительности, требования к базам данных.
Все это — не более чем контрольный список свойств системы, указываемый в требованиях. Поскольку многие из этих свойств могут влиять на успех разработки, следующий стандарт помогает авансом избежать дорогостоящих ошибок.
Программная система почти всегда является частью большой системы. Встроенное ПО, скажем, в цифровую камеру или мобильный телефон, является частью системы, включающей аппаратуру. Бизнес-ПО — это часть системы, включающей процессы компании. Одно из первых решений, которое приходится принимать при подготовке требований, — должны ли они относиться только к ПО или ко всей системе. Первый ответ не означает игнорирование системы, он предполагает, что будут заданы четкие интерфейсы между ПО и его окружением.
Еще одно важное разграничение, отмеченное ранее, — разграничение функциональных и не функциональных аспектов.
Обратите внимание на терминологию: "требование" — это элемент специфицируемого поведения, функционально или нефункционального, как в приведенных примерах. Требования — это коллекция таких индивидуальных элементов.
Процесс получения (или
Этот последний комментарий проясняет общее свойство сбора требований. Вы, возможно, полагаете, что в идеале процесс полностью создается на основе "потребностей пользователей": некоторая команда внимательно опрашивает клиентов, выясняя, что они хотят, записывает их ответы, сортирует, создает документ требований и вручает его команде разработчиков, которая и реализует желания клиентов. Так почти никогда не происходит. Так и не должно происходить.
Наблюдения показывают, что помимо простейшего случая сбора пожеланий клиентов и их последующей реализации, обычный процесс — итеративный: пользователи высказывают пожелания, разработчики предлагают легко реализуемые свойства и после нескольких итераций останавливаются где-то посередине. Такие обсуждения могут носить креативный характер, в результате могут появиться требования, которые ранее ни одна из групп и не предполагала.
Процесс принятия требований должен поддерживать эту модель. Практическое правило состоит в том, что разработка не должна начинаться до одобрения документа требований. Он должен быть подписан заказчиком с правом ответственной подписи и руководителем группы разработки. Многих ошибок в проектах можно было бы избежать, придерживаясь этого простого правила.
Иногда компания создает документ требований, не имея команды разработчиков, внешней или внутренней, так что описанный процесс становится неприменимым. Идея в таких случаях понятна - вначале определить требования, а потом выбрать команду, наилучшим образом реализующую требования. Это рискованная практика. Она может приводить к нереализуемым требованиям. Риск особенно возрастает, если на этом этапе привлекать внешних консультантов для проведения анализа требований. Мне неоднократно доводилось видеть для индустриальных проектов, что такой процесс приводит к завышенным требованиям. Слишком велико желание сделать приятное заказчикам, давая обещание, выполнять которое должен кто-то другой. В таких ситуациях в лучшем случае требования будут неизбежно пересмотрены, в худшем - реализация приведет к задержкам или неудаче.
Приемы для сбора требований включают:
интервью. Представители разных категорий сопричастников опрашиваются с целью выяснения, что они ждут от новой системы или от изменения существующей. Интервью должны быть тщательно подготовлены, включать вопросы по отдельным разделам и иметь открытую часть для пожеланий в свободной форме. Общей практикой является видеозапись интервью, чтобы к нему можно было бы возвращаться при необходимости;
семинары. Сбор в одном месте опрашиваемых людей может быть лучше, чем индивидуальные интервью. В этом случае часто на месте удается устранить разногласия, возникающие у разных групп сопричастников;
предыдущие системы. Редко, когда система начинается на пустом месте. Обычно уже существует система, отвечающая тем же потребностям. Изучение существующих систем, их достоинств и недостатков, является важной частью сбора требований. Одним из технических требований в таких ситуация может быть требование, чтобы новая система, по меньшей мере, работала не хуже старой и давала те же результаты в сравнимых случаях;
конкурирующие системы. Необходимо знать, что предлагают конкуренты. Даже если речь идет о внутренней разработке, полезно знать, как справляются с этим конкуренты, имеющие те же потребности.
Одним из продуктов, входящим в состав требований, должен быть глоссарий (в стандарте IEEE это раздел 1.3 "Определения, акронимы, аббревиатуры").
Каждая проблемная область имеет свой жаргон. Эксперты в этой области используют его в интервью и семинарах, предполагая, что интервьюер понимает его и что остальные эксперты понимают его так же, как и они. Оба предположения могут оказаться неверными. Первой задачей документа требования является перечисление употребляемых терминов и определение их точного технического смысла. Соберите все такие определения в глоссарий, покажите его экспертам, чтобы убедиться, что они согласны с вами и друг с другом. Глоссарий является одним из принципиальных ресурсов для процесса разработки требований. Но он используется не только для этих целей, поскольку многие концепции, перечисленные в глоссарии, будут необходим прямым двойникам (классам, компонентам) в программах.
При написании требований всегда следует четко разграничивать машинные и проблемные свойства (о чем убедительно сказано в книге Майкла Джексона, см. ссылку в конце лекции).
(рис 10.1) Майкл Джексон (2004)
Любая система функционирует в некоторой проблемной области со своими законами: в электронике действуют физические ограничения на скорость сигнала, в банковской сфере — своя система правил. Программная система, появляющаяся в результате разработки, может рассматриваться, как уже говорилось, как своего рода машина со своими законами. Джексон указывает на необходимость разграничений двух категорий требований.
В кратком тексте, описывающем Парижское метро, утверждение "У метро есть важное свойство — всегда существует маршрут для любой пары станций метро (математики бы сказали, что метро задается связным графом)" — является проблемным свойством. Любая программная система, связанная с метро, должна гарантировать выполнение этого свойства. Правило, нумерующее станции с юга на север (явно введенное "для упрощения жизни"), является машинным правилом, которое описывает частное соглашение, выбранное в конкретной модели метро.
Помимо необходимости понимания проблемной области возникает еще одна новая задача, отличающаяся от инженерии требований, — инженерия проблемной области, направленная на моделирование общих свойств проблемной области. Инженерия проблемной области не связана с конкретным проектом, но помогает процессу задания требований для всех проектов данной проблемной области. Например, компания, которая регулярно разрабатывает проекты, связанные с управлением движения поездов, может инвестировать средства в моделирование общих свойств железнодорожных систем.
Требования являются комбинацией машинных и проблемных ограничений. Слишком часто документы требований не разграничивают эти два вида требований. В результате читатели документа, в частности, разработчики, не понимают четко, что является следствием внешних обстоятельств (скорость света изменить нельзя), а что может быть пересмотрено при эволюции системы. По этой причине важно в документе требований специфицировать их природу — машинную или проблемную — для каждого частного требования.
Давайте дополним наш обзор рассмотрением свойств — пятнадцати свойств, — которым должны удовлетворять хорошие требования. Рассмотрим требования к требованиям. Должен заметить, что я никогда не видел документ, удовлетворяющий всем этим свойствам, но они обеспечивают ясное понимание принципов, которым должен следовать каждый разработчик требований. Некоторые, но не все, отвечают стандарту IEEE, ниже они отмечены звездочкой.
Требования должны быть обоснованными. Каждое индивидуальное требование должно иметь источником идентифицируемую и явно установленную потребность сопричастника.
Требования должны быть корректными *. Любая система, удовлетворяющая требованиям, должна отвечать потребностям сопричастников. Формально это невозможно гарантировать. Неформально нужно быть уверенными, что все сопричастники знакомы с требованиями и согласны с относящимися к ним требованиями.
Требования должны быть полными. Они должны покрывать все потребности сопричастников. В принципе, полнота не проверяема, так как возникает естественный вопрос — полнота по отношению к чему? Любой ответ будет ссылаться на некий более высокий уровень, новый документ, куда и переносится решение проблемы. На практике существуют полезные эвристики, основанные на концепциях, введенных ранее в этой книге.
Подобно классу, каждая система обеспечивает команды и запросы. Можно выполнять некоторые действия и можно запрашивать информацию. Документ требований должен описывать как команды, так и запросы. Информации должно быть достаточно, чтобы читатель требований мог определить, как выполнение любой команды будет воздействовать на любой из доступных запросов.
"Достаточная полнота" - технический термин, введенный в 1978 году в статье Гутта-га и Хорнинга для характеристики свойств абстрактных типов данных, теоретической основы ОО-программирования.
Требования должны быть согласованными. Они не должны включать противоречий. Этого на удивление трудно достигнуть. Трудность частично связана с размером многих индустриальных документов требований, которые могут составлять сотни и тысячи страниц для сложных систем. Несогласованности прокрадываются в документ. На странице 235 утверждается, что шлагбаум должен опускаться до звукового сигнала, свидетельствующего о приближении поезда, а на странице 1232 утверждается обратное. Программисту нужно выбрать что-то одно. На этапе принятия требований несогласованности должны быть обнаружены и устранены.
Заметьте разницу между согласованностью и корректностью: согласованность - внутреннее свойство документа требований, корректность указывает на удовлетворение некоторым
Требования должны быть недвусмысленными. Задача трудновыполнимая, поскольку документы требований пишутся на естественном языке с присущей ему неоднозначностью. Рассмотрим пример:
Фоновый менеджер задач должен обеспечивать сообщения о статусе с регулярными интервалами, не превышающими 60 секунд.
Пример взят из "SoftwareRequirements", см. ссылку в пункте "Дальнейшее чтение".
Разработчики системы по-разному могут истолковать это требование, некоторые интерпретации могут не устраивать пользователей. Эксперт по требованиям, процитировавший этот фрагмент, предложил в качестве замены некоторые варианты (сделав некоторые предположения о намерениях, которые можно было бы проверить у пользователей).
Это значительно более точный и типичный стиль для индустриальных требований. Пример является хорошей иллюстрацией тех трудностей, которые возникают при задании требований, он позволяет понять, почему тщательно написанный документ требований может занимать тысячи страниц.
Естественные языки не способствуют точности описаний. По этой причине во многих работах предпринимаются значительные усилия по использованию математических приемов для задания требований, называемых в этом случае формальными спецификациями.
Статья о "Формализме в спецификациях", см. ссылку в конце лекции в разделе "Дальнейшее чтение", обсуждает преимущества и недостатки такого подхода.
Требования должны быть осуществимыми. Вполне возможно "витание в облаках" при задании требований, особенно, как отмечалось, если требования пишут не те, кто будет их реализовать. Серьезный процесс включает ограничение амбиций и понимание возможностей.
Требования должны быть абстрактными. Типичный просчет при подготовке требований состоит в попытках задания решений, которые следует принимать на последующих этапах проектирования и реализации. Такая сверхспецификация сужает возможности и не соответствует миссии требований, которые должны говорить, что нужно делать, но не определять, как делать.
Требования должны быть прослеживамыми*. Другими словами, должна быть возможность проследить в коде и в других программных продуктах все последствия каждого индивидуального требования. Это позволяет не только проверить, чтобы предлагаемая реализация удовлетворяла всем требованиям, но и при изменении требования проследить за всеми программными элементами, затронутыми этим изменением.
Примером механизма прослеживания в EiffelStudio является средство, названное
Требования должны быть верифицируемыми*. Бесполезно задавать требование, если нет способа проверки его выполнения в программной системе. Экстремальным — но, к несчастью, распространённым — примером неверифицируемого требования является требование в форме "система должна работать в реальном времени, выполняя команды и запросы". Но что такое "реальное время", может оставаться загадкой. Для банковской системы ответ на запрос в течение 2-х секунд — это реальное время, для сетевых устройств реальным временем может быть 100 микросекунд. Документ должен указывать точные значения, задавая среднее значение и допустимые отклонения.
Требования должны быть ограничительными. Важно установить не только то, что система должна делать, но и то, что лежит за пределами ее компетенции.
Требования должны задавать интерфейс. Следует точно установить связи системы с внешним миром — людьми, аппаратурой, другими программными системами.
Требования должны быть приоритетными*. Иногда обстоятельства заставляют отказаться в проекте от полной реализации всего, что было запланировано. Типичной причиной отказа является урезание бюджета.
Причиной могут стать неожиданно возникшие трудности, приводящие к задержке проекта, и, как следствие, ограничение функциональности, чтобы проект мог выйти в запланированные сроки. Иногда приходится форсировать выпуск, чтобы опередить конкурирующий продукт. Выбор того, чем следует пожертвовать, не должен приниматься спонтанно. Требования должны устанавливать важность каждой функциональности, это позволяет делать выбор на основе предварительно согласованных приоритетов.
Требования должны быть понятными. Стремление к точности и детализации может в результате дать обратный эффект, приводя к громоздким документам. Если требования не будут просты для понимания, они не сыграют свою роль.
Требования должны быть модифицируемыми*. Меняются обстоятельства, меняется сознание людей, компании могут сливаться. Подобно любым другим программным продуктам, требования должны проектироваться с учетом возможных изменений.
Ну и, наконец, требования должны быть одобрены и подписаны. Так много места для непонимания и конфликтов, что не следует начинать разработку проекта без ясного формального понимания, включающего, по крайней мере, подписи людей, ответственных за проект с двух сторон — со стороны заказчика и со стороны команды разработчиков.
Надеюсь, я не напугал вас этим длинным списком критериев хороших требований. Документ хороших, хотя и не совершенных требований написать вполне возможно, он будет отображать потребности сопричастников проекта и будет служить основой для разработки и ВП-реализации. Это важная часть разработки ПО и великолепная возможность комбинировать технологию с бизнесом, учитывая при этом психологию людей.
Первое правило ВП говорит, что было бы прекрасно, если бы этого не нужно было делать. Цель всех правил проектирования и методологии программирования, изучаемых в этой книге (а я верю, что вы будете применять каждое из них при каждом подходящем случае), состоит в том, чтобы создавать программный продукт, который будет работать с первого раза и каждый раз. Но все же нужно убедить в этом остальной мир, не исключая возможности, что ошибки могут встретиться и в вашей работе. Кроме того, иногда ведь приходится модифицировать продукт, написанный другим, менее просвещенным программистом. На практике ВП является главной частью усилий при разработке проекта, часто занимающей больше времени, чем само конструирование ПО.
Ограничим себя обзором некоторых базисных идей. Обсуждение главным образом коснется программ, хотя, как отмечалось, ВП применима и к непрограммным артефактам, таким как документация. Термин "страхование качества ПО" будет использоваться как синоним ВП.
Это некоторое насилие над языком, так как страхование качества включает методы построения качественного ПО и методы оценивания качества построенного ПО.
Многие люди под ВП понимают только тестирование и отладку. Фактически, область применения методов ВП значительно шире. Тестирование — главный вид динамических методов — заключается в выполнении системы (поэтому и динамический метод) на выбранных входах. Цель тестирования — обнаружение дефектов.
Статические методы анализируют текст программы без ее выполнения. Они включают осмотр кода, его статический анализ, доказательство корректности, проверку на соответствие модели.
Наше рассмотрение начнем с тестирования, а затем перейдём к статическим приемам. Следующие термины, полезные при обсуждении, идут от еще одного IEEE-стандарта по терминологии инженерии программ.
IEEEStd 610.12-1990, tinyurl.com/3w57pk (текст 1990 года, но во многом все еще полезен).
Выполнение программы, не функционирующее, как ожидалось (дает неверные результаты или приводит к аварийному завершению), называется отказом (failure).
Отказ (за исключением редких случаев отказа аппаратуры) — следствие дефекта (fault) ПО, свидетельствующее, что ПО работает не так, как должно. Заметьте, что дефект не обязательно является ошибкой реализации, он может возникать из-за ошибок на любом уровне, таких как спецификация или проектирование.
Дефект является следствием ошибки (mistake), сделанной разработчиком ПО. Термин "баг", или "жучок", не является частью официальной терминологии, хотя часто
используется для обозначения дефектов или ошибок чаще всего при отладке — задаче исправления ошибок, удаления дефектов и устранения отказов.
Начнем с тестирования — наиболее применяемой программистами техники. Первое наблюдение свидетельствует о скромной роли тестирования, поскольку оно не дает гарантий качества. Причина была указана Эдсгером Дейкстрой, это его высказывание является одним из наиболее цитируемых в истории информатики: "Тестирование может показать наличие ошибок, но не их отсутствие".
Ошибочный тест выявляет дефект, успешный тест мало о чем говорит, так как в любой реальной программе число тестов невероятно велико. Даже программа, которая умножает два числа из 64-х битов, имеет 2128 вариантов.
Комментарий Дейкстры справедлив, но он не свидетельствует о грехах тестирования. "Показать наличие ошибок" — дело, чрезвычайно полезное для практики, позволяющее нам найти ошибки до того, как их найдут пользователи. Тестирование — это техника обнаружения ошибок.
За последние годы технология тестирования существенно прогрессировала. Эволюция шла в направлении большей автоматизации. Для всех известных языков программирования появились специальные инструментальные средства — каркасы, позволяющие записывать тесты и автоматически запускать систему тестов. Эти средства известны под общим именем "XUnit", следуя названию JUnit — каркасу Java. Их широкий успех объясняется тем, что альтернативный способ — ручное управление и выполнение тестов — стал нереалистичным для современных программ, требующих запуска большого числа тестов. Мощь компьютеров сделала возможным проверку системы на многих тестах, но для этого требуется автоматическая поддержка.
Автоматизация, в частности, необходима для задачи, известной как регрессионное тестирование. Имеет место факт, удивительный для новичков, но характерный для разработки ПО,— исправленные дефекты могут вновь появляться в последующих релизах (ПО частично регрессирует к прежнему состоянию, отсюда и название — регрессионное тестирование). Причины регрессии следующие:
Регрессионное тестирование пытается захватить все такие случаи, выполняя все тесты, на которых возникала ошибка. Каждый серьезный проект выполняет регрессионное тестирование при каждом новом выпуске системы. Это отражается в следующем принципе.
Современные исследования автоматизации тестирования идут значительно дальше. Примером новых возможностей является каркас — EiffelTestFramework, который, начиная с версии 6.3, стал интегральной частью EiffelStudio. Здесь в добавление к стандартному механизму "XUnit" появились два продвинутых свойства.
Тестирование — активно развивающаяся область исследований, так что можно ожидать появления новых инструментариев и новых возможностей в будущих средах разработки.
Возвращаясь назад, к сегодняшней технологии тестирования, стоит рассмотреть несколько новых понятий (за деталями следует обратиться к учебникам по инженерии программ и литературе по тестированию).
Тестирование встречается на разных уровнях гранулярности.
Юнит-тестирование (модульное тестирование) предназначено для тестирования отдельных модулей — типично классов или кластеров в ОО-разработке. Обычно оно выполняется индивидуальными разработчиками соответствующих модулей.
Интеграционное тестирование оценивает, как выполняется группа модулей или подсистем при их соединении. Обычно это задача группы разработчиков, возможно, выполняемая специализированным подмножеством — командой тестеров или командой страхования качества.
Системное тестирование тестирует систему в целом. Часто этот шаг по-прежнему выполняется командой тестеров. Приемочное тестирование предполагает тестирование с позиций заказчика, и ответственность за него лежит на организации заказчика, оно выполняется объединенной группой представителей разработчиков и заказчика.
Для юнит-тестирования принято различать два подхода — черный и белый ящики. При тестировании белого ящика доступен текст программы, позволяющий руководить процессом тестирования, в то время как тестирование черного ящика целиком основано на
В заключение отметим концепцию покрытия тестов, применимую главным образом к белым ящикам. Покрытие — это мера качества набора тестов, позволяющая оценить объем протестированной функциональности. Меры покрытия могут включать:
Существует много других критериев покрытия, хотя в конечном итоге считать нужно было бы, каков процент обнаруженных ошибок дает данный набор тестов. Этот критерий может коррелировать или не коррелировать с элементарными мерами покрытия. Обобщение черного ящика приводит к понятию покрытия спецификации, дающего оценку, как много случаев, допускаемых спецификацией, были испытаны.
Закончим обзор ВП рассмотрением статических методов.
Обзор проекта и кода, называемый также инспекцией, является процессом, выполняемым вручную для обнаружения дефектов и других неисправностей. Целью инспекции типично бывает программный элемент, за разработку которого отвечает один исполнитель. Таким элементом может быть класс, но может быть и глава из руководства пользователя. Текст пускается по кругу, а затем обсуждается на встрече в интересах обнаружения возможных проблем. Встреча не имеет других целей — не оценивается сам разработчик и не предполагается исправление обнаруженных проблем (эту задачу будет решать разработчик самостоятельно после встречи).
Это описание классической идеи обзора кода. С наступлением эры Интернета и все большим распространением географически распределенных команд разработчиков этот процесс может использовать возможности удаленного доступа и видеоконференций. Один из уроков такого опыта состоит в том, что обзор становится более эффективным, если частично сопровождается написанием замечаний. Процесс начинается еще до встречи, когда участники аннотируют общий документ (технология разделения Web-документов теперь широко доступна). По большинству замечаний на этом этапе разработчик и его критики приходят к согласию. На встречу (видеоконференцию) выносятся вопросы, требующие дополнительного обсуждения.
Моя статья "Design and Code Reviews in the Age of the Internet" (Communications of the ACM, vol. 51, no. 9, September 2008) описывает этот процесс в деталях.
Нельзя ожидать, что инспекция кода является эффективным инструментом для систематического обнаружения дефектов. Обзор кода является процессом, требующим больших затрат времени разработчиков — самого дорогого ресурса. Хорошей идей является применение этого подхода для критически важных модулей. Главная же цель выполнения обзоров состоит в оценке общих практик проектирования и кодирования, применяемых в команде, особенно практик, способных повредить качеству системы. Крайне важно, когда обзор выявил недостатки, выявить их причины и понять, какие же методы могут быть использованы, чтобы избежать подобных ошибок в будущем.
Более эффективный процесс статического анализа требует автоматизированного инструментария. Компилятор статически типизированного языка включает статический анализатор, являющийся частью компилятора и обеспечивающий безопасность системы типов. Помимо прямой реализации правил языка программирования статический анализатор ищет образцы кода, которые могут приводить к ошибкам, даже если они явно не нарушают правила языка. Примеры включают:
Специальной формой статического анализа является доказательство корректности программ — наиболее амбициозный и наиболее трудный подход. Термин "доказательство" используется в математическом смысле и, следовательно, предполагает некий формализм при задании спецификаций. Контракты Eiffel дают представление о том, как может выглядеть такой формализм: каждый программный элемент характеризуется предусловием и постусловием (для методов) или инвариантом (для класса). Это абстрактные спецификации функциональности. Для полного доказательства спецификации должны быть детализированы, но общая идея остается применимой. "Доказательство" класса тогда означает установление математическими методами, что реализация удовлетворяет спецификации: каждый метод, запущенный в состоянии, удовлетворяющем инварианту и предусловию, будет завершать свое выполнение в состоянии, удовлетворяющем постусловию и инварианту.
Эта форма спецификаций согласована с наблюдением, приведенным ранее в этой лекции, что корректность программы может быть определена только по отношению к заданной спецификации. Здесь спецификации принимают форму контрактов, а корректность означает, что реализация согласована с контрактами.
Поскольку такие доказательства требуют включения многих деталей, а также и потому, что доказательствам, сделанным человеком, нельзя полностью доверять (ошибки в доказательствах возможны не в меньшей степени, чем ошибки в программе), процесс должен основываться на автоматически работающем инструментарии, выполняющем доказательство корректности программ. Многие такие программы представляют надстройку над программами, доказывающими правильность теорем, способных выполнять математические выводы. Работы над автоматизацией методов доказательства ведутся десятилетиями; в последние годы они получили новые импульсы благодаря продвижениям в технологии доказательств и лучшего понимания проблем. Это активно развиваемая область исследований.
Наиболее впечатляющий прогресс достигнут в направлении, где обычно не пытаются дать полное доказательство корректности, но фокусируются вместо этого на идентификации специфических отказов, — то, что обычно делает тестирование.
Что это дает, можете вы спросить, для повседневной практики программирования? Это во многом зависит от места вашей работы. Долгое время формальные методы — доказательства и связанные приемы — рассматривались как интеллектуально привлекательные идеи, не применимые в индустриальных разработках (назвать подход "академическим" равносильно "поцелую смерти"). Эта точка зрения сегодня уже не доминирует. При постоянном улучшении как теории, так и инструментария, и с возрастающей опасностью рисков неверно функционирующих программных систем растет число индустриальных разработок, использующих формальные методы и инструменты. Некоторые из уроков обнадеживают, некоторые разочаровывают.
Все эти свойства современной технологии облегчают конструирование больших программ с элегантной архитектурой, открытой для расширения и повторного использования, предоставляя программистам выразительную мощь языка программирования. В результате формальные методы пока применяются в той области, где существует один критерий — корректность. Сюда относятся жизненно важные системы, такие как системы управления самолетами или поездами, где должно быть сделано все, чтобы избежать ошибок функционирования. Пример ПО "Аэробуса" является показательным.
Остальная часть индустрии обычно не готова принять такой вид аскетизма, который требует техника доказательств от своих последователей. Ведутся серьезные исследования, чтобы сделать их более применимыми в главных направлениях разработки ПО. Тони Хо-ар выступил с инициативой "
Наша последняя тема этой лекция посвящена общему организационному подходу, который применяется в компаниях последние годы. Он соответствует духу идей моделей жизненного цикла, обсуждаемых ранее в этой лекции, но расширяет их рамки.
Предположим, что вашей организации необходимо заключить контракт на разработку ПО с некоторой программистской компанией. Пока нет продукта, который можно было бы оценить, так что оценке может подлежать только сам процесс разработки. Компания убеждает вас, что у нее все находится под контролем, но как это проверить?
В начале 90-х годов необходимость объективной оценки программистских фирм возникла у Министерства обороны Соединенных Штатов — крупнейшего заказчика ПО для своих нужд. Для решения этой задачи Институту программной инженерии Университета Карнеги-Меллона был сделан заказ на разработку модели, определяющей уровень зрелости программистских фирм. Разработанная ими модель получила название "Capability Maturity Model" (акроним CMM), а позже модель была расширена и стала называться CMMI-моделью — "интеграционная модель зрелости и способностей". Эта модель оказала существенное влияние на некоторые сегменты рынка ПО, в частности:
Модель CMMI используется и вне этих сообществ. Доля организаций, работающих с оборонными заказами и сертифицированных по CMMI, неуклонно сокращается, в 2004 году она составляла
Некоторые компании в поисках процесса улучшения организации работ и квалификации предпочитают другие модели. Серия стандартов 9000 ISO также устанавливает международные стандарты качества. Стандарт SPIQE комбинирует элементы предыдущих двух стандартов. В этом обзоре рассматривается только CMMI.
CMMI и другие модели исследуют только процессы. Они нейтральны к используемым технологиям, языкам и инструментарию. Все они оценивают, имеет ли организация набор четких процедур для каждого рода деятельности, применяются ли эти процедуры, контролируется ли их применение, измеряется ли эффект, прилагаются ли усилия по их улучшению. Вспоминая предыдущее наше обсуждение о качестве ПО, скажем, что модели следят за факторами процесса, особенно за последними пятью из нашего списка.
Процесс сертификации аналогичен проверке пилотом самолета перед вылетом
Из-за акцента на формальные процедуры в ущерб технологиям ряд специалистов критически относятся к моделям процессов, полагая, что они главным образом служат интересам менеджеров проекта, подкладывающих соломку на случай неуспеха проекта, — они делали все по инструкции. И в самом деле, известны случаи провала проектов в организациях с высоким уровнем сертификации CMMI или ISO. Но это классический пример, когда выполняется необходимое, но не достаточное условие. Программным проектам, особенно большим, необходимо высокое качество процессов, но этого недостаточно, им для успеха необходима также и выдающаяся технология.
Ключевым в CMMI является понятие оценивания. Организации, желающие установить свой уровень зрелости, могут сделать это, обратившись к официальным оценщикам, аккредитованным в Институте программной инженерии. В 2005 году Институт аккредитовал 179 оценщиков, главным образом организации, занимающиеся такого рода деятельностью. Организации, получившие сертификат об уровне их зрелости, могут опубликовать его и использовать в рекламных целях для повышения своей привлекательности.
Как указывает буква "I" в акрониме (Integration), CMMI пошла дальше CMM для того, чтобы расширить сферу воздействия на модели, отличные от программных. Четыре дисциплины кроме инженерии программ включают также:
Организации, реализующие CMMI и желающие получить сертификат, могут выбирать любую из этих дисциплин в зависимости от их деятельности и потребностей.
Основа CMMI — определение целей и рекомендуемых практик.
Как показывают примеры, каждая практика должна быть связана с некоторой целью. Если использовать программистскую технологию, то цель — это спецификация, а практика — ее реализация (выполняемая людьми).
Цели и соответствующие им практики группируются в коллекции, называемые областью процесса. Приведенные примеры могут рассматриваться как часть области процесса "Разработка требований".
Термин "область" не является интуитивно понятным, так что просто следуйте определению — область, содержащая коллекцию целей и практик, поддерживающих эти цели.
CMMI существует в двух вариантах — ступенчатом, или поэтапном, и непрерывном.
Общим для обоих вариантов является понятие уровня оценивания. В поэтапном варианте организация получает оценку от 1 до 5 (как в школе). Чем выше оценка, тем выше уровень контроля процессов. В непрерывном варианте оценивается каждая область, здесь добавляется уровень 0, свидетельствующий о том, что организация не занимается этой конкретной областью процессов.
В поэтапном варианте каждый уровень характеризуется своим набором областей процессов. Вы достигаете соответствующего уровня, если отвечаете соответствующим целям и применяете нужные практики. Например, для достижения уровня 2 необходимо удовлетворять области процесса "Управление требованиями" и другим областям, перечисленным ниже. Кроме того, каждый уровень имеет родовую цель и связанное множество родовых практик. Для уровня 2 родовой целью является "Организация управляемого процесса", означающая, что в компании определён процесс разработки и принимаются меры по его соблюдению. Связанными родовыми практиками являются такие практики, как "Планирование процесса" и "Обеспечение ресурсами".
Как следствие этих концепций, цели и практики разделяются на две категории.
Дадим общую характеристику уровней для поэтапного варианта. Более точное определение дается ниже приводимой таблицей, которая идентифицирует в отдельности родовые и специфические цели. Как говорилось, выделяется пять уровней.
Следующая таблица более точно описывает, что должно достигаться на каждом уровне (начиная со 2-го, поскольку по определению на уровне 1 нет точных требований).
| Уровень | Имя | Области процессов |
|---|---|---|
| 2 | Управляемый | |
| 3 | Определенный | |
| 4 | Количественно управляемый | |
| 5 | Оптимизирующий |
CMMI определяет на каждом уровне точное множество целей и практик. Мы не будем заниматься этими деталями, надеясь, что вы разберетесь с ними сами, изучая литературу по CMMI, где вы сможете найти и метод, известный как персональный процесс разработки, который применяют индивидуальные разработчики, руководствуясь изложенными идеями.
Carlo Ghezzi, Mehdi Jazayeri and Dino Mandrioli: Fundamentals of Software Engineering, 2nd Edition, Prentice-Hall, 2002.
Хорошо известный учебник по инженерии программ, дающий полное представление о предмете. Другими хорошими учебниками являются: S.L. Pfleeger, J. Atlee (3rd edition, Prentice Hall, 2005) и Roger Pressman (6th edition, McGraw Hill, 2005).
(рис 10.2) Карло Чеззи (2008) Дино Мандриоли (2008)
IEEE
Доступна при условии регистрации на сайте: ieeexplore.ieee.org/xpl/tocresult.jsp?isNumber =15571
Краткий стандарт, описывающий лучшие практики написания документов требований, включая рекомендуемую структуру документа, которая широко применятся в индустрии.
Bertrand Meyer: On Formalism in Specifications, in IEEE Software, vol. 3, no. 1, January 1985, pages 6-25.
Доступна на сайте: se.ethz.ch/~meyer/publications/computer/formalism.html
Старая статья, объясняющая, почему полезно для задания спецификаций использовать математические методы.
John V. Guttag and James J. Horning: The
Конструктивная статья по теории абстрактных типов данных, лежащих в основе объектной технологии. Вводит понятие "достаточной полноты".
(рис 10.3) Джим Хорнинг (2007)
KarlE. Wiegers: SoftwareRequirements, MicrosoftPress, 2003.
Набор полезных правил для написания хороших документов требований.
Michael Jackson: Software Requirements and Specifications: A
Прекрасное обсуждение требований и спецификаций.
Axel
Еще одна прекрасная книга по требованиям, наиболее современная, от одного из авторитетов в этой области. Хорошая теория и примеры. Bertrand Meyer and Jim Woodcock (editors): VSTTE (Verified Software: Theories, Tools, Experiments),
Труды содержат работу Тони Хоара "GrandChallenge". Хорошая оценка состояния искусства
Frederick P.
На русском языке: "Мифический человеко-месяц" см., например, на сайте: http://www.webkomora.com.ua/ru/articles/web/management/man-month.html
Фред Брукс из IBM управлял разработкой OS/360, одной из первых сложных операционных систем, доступной на серии компьютеров. Эта книга, где он суммирует свой опыт в коротких эссе, должна быть упомянута, так как считается классикой в инженерии программ, она в большой степени стала народным фольклором.
(рис 10.4) Фредерик Брукс (2007)
Software Engineering Institute: Capability Maturity Model Integration (CMMI)
Обзор, доступный на сайте: http://www.sei.cmu.edu/cmmi/adoption/pdf/cmmi-overview07.pdf
Software Engineering Institute: Capability Maturity Model® Integration (CMMISM), Version 1.1, CMMISM for
Доступна на сайте: tinyurl.com/kf9uy (
Это официальное, детальное описание CMMI, поэтапного представления.
Непрерывный вариант: tinyurl.com/gjla9
(рис 10.5) Уотс Хэмпфри (2007)
Описывает персональный процесс разработки —
| Adequacy | Адекватность | Built-in assessment | Встроенное оценивание |
| Correctness | Корректность | Correctibility | Способность к изменениям |
| Cost control | Управление стоимостью | Efficiency | Эффективность |
| Extendibility | Расширяемость | Factor (of software quality) | Фактор (качества ПО) |
| Goal (CMMI) | Цель (CMMI) | Lifecycle | Жизненный цикл |
| Maintenance | Сопровождение | Measurability | Измеримость |
| Portability | Переносимость | Practice (CMMI) | Практика (CMMI) |
| Predictability | Предсказуемость | Process (vs product) | Процесс (в сравнении с продуктом) |
| Process area (CMMI) | Область процесса (CMMI) | Product (vs process) | Продукт (в сравнении с процессом) |
| Production software | Производство ПО | Reproducibility | Воспроизводимость |
| Reusability | Повторное использование | Robustness | Устойчивость |
| Security | Безопасность | Self-improvement | Самоулучшение |
| Software engineering | Инженерия программ | Stakeholder | Сопричастник |
Дайте точное определение терминам словаря.
Могут ли сопричастники программного проекта быть соперниками? Обсудите, в какой части они или концепции о них могут играть роль в построении ПО и управлении проектом.
В обзоре CMMI, указанном в разделе "Дальнейшее чтение", приводится высказывание (и его критика) неназванного старшего менеджера: "Я бы предпочел вовремя выпустить проект с ошибками, чем опоздать с выпуском. Позже мы всегда сможем исправить ошибки". Обсудите это высказывание с позиций инженерии программ.
Для получения официальных документов о завершении программы дополнительного профессионального образования (удостоверения о повышении квалификации, дипломов о профессиональной переподготовке и MBA) необходимо предоставить:
Внимание! Вы можете не заказывать доставку бумажной версии официального документы, а скачать его в электронном виде и распечатать самостоятельно. Информация о выданном документе в течение 1 месяца загружается в Федеральную информационную систему «Федеральный реестр сведений о документах об образовании и (или) о квалификации, документах об обучении» - ФИС ФРДО.
Доступ на новый сайт осуществляется с использованием адреса электронной почты, который был указан вами при регистрации на "старом". Мы постарались перенести все ваши данные с прежнего ресурса, однако не исключена вероятность потери части информации.
При возникновении проблемы со входом, воспользуйтесь функцией сброса пароля
Если вы обнаружите несоответствия, пожалуйста, сообщите нам.