Разработка программного продукта при моделировании экологических систем


Введение

Методические указания предназначены  для изучения основных понятий, определений, принципов и  закономерностей, используемых в теории игр и теории принятия решений  применительно к экономике сельского  хозяйства, а также для приобретения практических навыков постановки и решения прикладных задач в данной предметной области.

В число задач методических указаний не входит изучение всех проблем, решение которых связано с  применением теории игр и теории принятия решений. В них отражены только основные аспекты применения данных знаний в экономической практике.

Изучение данных методических указаний необходимо для освоения учебных  дисциплин: «Игровые модели и принятие решений», «Исследование операций в  экономике».

 

1 Теоретическая часть

1.1 Описание жизненного цикла программы

Рассмотрим несколько  описаний жизненного цикла программного обеспечения, которые послужат своеобразным комментарием этапам обобщенного жизненного цикла.

В отечественных нормативных  документах (например, ГОСТ ЕСПД) принято  следующее разграничение на этапы, которое приводится с указанием аналогий из списка, данного в начале раздела:

  • разработка технического задания;
  • технический проект;
  • рабочий проект;
  • экспериментальное внедрение;
  • сдача в промышленную эксплуатацию;
  • промышленная эксплуатация.

Подобное описание имеет  своим прообразом технологию разработки аппаратных средств и поэтому  не вполне учитывает все отличительные  особенности проектирования программ. Более подходящим выглядит описание жизненного цикла программного обеспечения, состоящее из 12 этапов, которые очень близки этапам обобщенного жизненного цикла (см. рис. 1). В скобках после имени фазы указывается аналог из обобщенного цикла. Практически все этапы заканчиваются проверкой результатов, полученных на соответствующем этапе.

 

 

 

Рисунок 1 - Пример жизненного цикла программных систем

  1. Начало проекта и планирование. Определяются необходимые действия, планы и организация управления проектом. Определяются меры по обеспечению непрерывного выполнения фаз жизненного цикла.
  2. Анализ целевых требований. Определяются, без учета средств реализации, общие характеристики системы, которым она должна удовлетворять. Устанавливается, что и как должна делать система.
  3. Анализ системных требований. Описывается, как должны удовлетворяться запросы пользователя, в терминах конкретных функциональных понятий описываются действия предполагаемой системы, хранимые данные, используемый интерфейс - все это без учета физической реализации. Проверяется пригодность этих конкретных понятий.
  4. Проектирование системы. Устанавливается структура системы или, иначе говоря, ее архитектура в терминах основных компонентов этой системы и их предполагаемой реализации (аппаратной, программной, с помощью окружения и т.д.). Устанавливаются требования для каждого компонента, а также стратегию тестирования и интеграции.
  5. Предварительное проектирование программного обеспечения. Определение конкретных программных компонент, которые будут разрабатываться, и внедряться в конечную систему. Проверка этого множества компонент на непротиворечивость общим требованиям к программному обеспечению. Определение функциональных, эксплуатационных и тестовых требований к каждому конкретному компоненту.
  6. Детальное проектирование программного обеспечения. В терминах используемых программных конструкций производится описание того, как каждый конкретный компонент будет разрабатываться. Описываются режимы использования каждого компонента в системе.
  7. Кодирование и тестирование программного обеспечения. Создание, тестирование отдельных модулей, документирование и приемка программных компонентов, которые составляют программную систему.
  8. Интеграция программного обеспечения. Тестирование работоспособности и функциональной законченности программных частей системы в предсказуемом окружении (аппаратуре и окружающей среде).
  9. Интеграция системы. Тестирование работоспособности и функциональной законченности частей общей системы в целом.
  10. Приемка и поставка системы. Производится приемка системы заказчиком, и поставка ему системы.
  11. Эксплуатация и сопровождение системы. Выпуск последующих вариантов или версий системы, необходимость в которых возникает из - за устранений дефектов, отработки измененных требований и т.д.
  12. Завершение проекта. Формирование посториорной модели проектных действий с анализом достоинств, недостатков и т.д., и использование их в качестве основания для улучшения процесса разработки.

В качестве следующего примера  рассмотрим неполный жизненный цикл программного обеспечения, без этапов эксплуатации и сопровождения (см. рис. 2). В этом варианте не фиксируется последовательность фаз или этапов, а предлагается перечень действий, которые должны быть выполнены на протяжении жизненного цикла программного обеспечения. Эти действия могут быть разбиты или, наоборот, сгруппированы в различные этапы, в зависимости от конкретных условий. Можно выделить следующие этапы жизненного цикла программных систем (в скобках, как и ранее, - аналоги из модели обобщенного цикла):

  1. этап планирования, который определяет и координирует действия по разработке программной системы;
  2. этап разработки, на котором создается программная система:
    • постановку задачи,
    • проектирование,
    • кодирование,
    • получение исполняемого кода.

Интегрированный этап, обеспечивающий коррекцию, проверку, и определение полноты программной системы, а также ее выпуск. Этот этап включает в себя верификацию, контроль за конфигурацией системы, оценку качества и проверку взаимодействия между этапами. Из названия этого этапа видно, что он выполняется совместно с другими этапами на протяжении жизненного цикла системы.

 

 

Рисунок 2 - Вариант упрощенного жизненного цикла программной системы

Отсутствие интегрированного этапа в обобщенном жизненном  цикле не означает, что проверка производится только там, где это  явно указано в названии этапа. Каждый этап может считаться завершенным  только тогда, когда результаты, полученные на данном этапе, были признаны удовлетворительными, а для этого необходимо производить проверку результатов на каждом этапе. В обобщенном жизненном цикле некоторые проверки были вынесены отдельными пунктами для демонстрации повышенных объемов, сложности и важности этих проверок.

Последовательность этапов жизненного цикла для разных программных  систем определяется такими характеристиками как функциональные возможности, сложность, размер, устойчивость, использование  ранее полученных результатов, разрабатываемая стратегия и аппаратное обеспечение.

На рис. 3 показана последовательность этапов разработки программного обеспечения для отдельных компонентов единой программной системы с различными жизненными циклами.

Рисунок 3 - Последовательность этапов разработки компонент программного обеспечения

Для компонента W из множества  системных требований к единому  продукту формируется подмножество требований, относящихся к данному  компоненту, используются эти требования при формировании проекта программного компонента, реализовывают этот проект в исходном коде и тогда интегрирует компонент с аппаратурой. Компонент X показывает использование ранее разработанного программного обеспечения. Компонент Y показывает использование простой отдельной функции, которая может быть закодирована прямо на основе требований к программному обеспечению. Компонент Z показывает использование прототипной стратегии. Обычно, целями прототипирования является лучшее понимание требований к программному обеспечению и уменьшение технических рисков и рисков разработки при создании конечного продукта. Исходные требования используются как базис для получения прототипа. Этот прототип преобразуется в окружение, типичное для конкретного использования системы при разработке. Результатом преобразований является уточненные данные, которые используются для создания конечного программного продукта.

1.2 Виды программной  документации

Перечень стандартов, входящих в ЕСПД (Единая система программной доку-ментации):

  • ГОСТ 19.001 - 77. ЕСПД. Общие положения.
  • ГОСТ 19.003 - 80. ЕСПД. Схемы алгоритмов и программ. Обозначения условные графические.
  • ГОСТ 19.005 - 85. ЕСПД. Р - схемы алгоритмов и программ. Обозначения условные графические и правила выполнения.
  • ГОСТ 19.101 - 77. ЕСПД. Виды программ и программных документов.
  • ГОСТ 19.102 - 77. ЕСПД. Стадии разработки.
  • ГОСТ 19.103 - 77. ЕСПД. Обозначение программ и программных документов.
  • ГОСТ 19.104 - 78. ЕСПД. Основные надписи.
  • ГОСТ 19.105 - 78. ЕСПД. Общие требования к программным документам.
  • ГОСТ 19.106 - 78. ЕСПД. Требования к программным документам, выполненным печатным способом.
  • ГОСТ 19.201 - 78. ЕСПД. Техническое задание. Требования к содержанию и оформлению.
  • ГОСТ 19.202 - 78. ЕСПД. Спецификация. Требования к содержанию и оформлению.
  • ГОСТ 19.301 - 79. ЕСПД. Программа и методика испытаний. Требования к содержанию и оформлению.
  • ГОСТ 19.401 - 78. ЕСПД. Текст программы. Требования к содержанию и оформлению.
  • ГОСТ 19.402 - 78. ЕСПД. Описание программы.
  • ГОСТ 19.403 - 79. ЕСПД. Ведомость держателей подлинников.
  • ГОСТ 19.404 - 79. ЕСПД. Пояснительная записка. Требования к содержанию и оформлению.
  • ГОСТ 19.501 - 78. ЕСПД. Формуляр. Требования к содержанию и оформлению.
  • ГОСТ 19.502 - 78. ЕСПД. Общее описание. Требования к содержанию и оформлению.
  • ГОСТ 19.503 - 79. ЕСПД. Руководство системного программиста. Требования к содержанию и оформлению.
  • ГОСТ 19.504 - 79. ЕСПД. Руководство программиста. Требования к содержанию и оформлению.
  • ГОСТ 19.505 - 79. ЕСПД. Руководство оператора. Требования к содержанию и оформлению.
  • ГОСТ 19.506 - 79. ЕСПД. Описание языка. Требования к содержанию и оформлению.
  • ГОСТ 19.507 - 79. ЕСПД. Ведомость эксплуатационных документов.
  • ГОСТ 19.508 - 79. ЕСПД. Руководство по техническому обслуживанию. Требования к содержанию и оформлению.
  • ГОСТ 19.601 - 78. ЕСПД. Общие правила дублирования, учета и хранения.
  • ГОСТ 19.602 - 78. ЕСПД. Правила дублирования, учета и хранения программных документов, выполненных печатным способом.
  • ГОСТ 19.603 - 78. ЕСПД. Общие правила внесения изменений.
  • ГОСТ 19.604 - 78. ЕСПД. Правила внесения изменений в программные документы, выполненные печатным способом.
  • ГОСТ 19.701 - 90 (ИСО 5807-85). ЕСПД. Схемы алгоритмов, программ, данных и систем. Условные обозначения и правила выполнения.

 

ГОСТ 19.503 - 79 ЕСПД Руководство системного программиста от 1980 года:

ОБЩИЕ ПОЛОЖЕНИЯ

1. Структуру и оформление  документа устанавливают в соответствии  с ГОСТ 19.105 - 78.

 

Составление информационной части (аннотации и содержания) является обязательным.

2. Руководство системного программиста должно содержать следующие разделы:

  • общие сведения о программе;
  • структура программы;
  • настройка программы;
  • проверка программы;
  • дополнительные возможности;
  • сообщения системному программисту.

В зависимости от особенностей документы допускается объединять отдельные разделы или вводить новые. В обоснованных случаях допускается раздел «Дополнительные возможности» не приводить, а в наименованиях разделов опускать слово «программа» или заменять его на «наименование программы».

СОДЕРЖАНИЕ  РАЗДЕЛОВ

1. В разделе «Общие сведения о программе» должна быть указаны назначение и функции программы и сведения о технических и программных средствах, обеспечивающих выполнение данной программы.

2. В разделе «Структура  программы» должны быть приведены  сведения о структуре программы, ее составных частях, о связях между составными частями и о связях с другими программами.

3. В разделе «Настройка  программы» должно быть приведено  описание действий по настройке  программы на условия конкретного  применения (настройка на состав технических средств, выбор функций и др.). При необходимости приводят поясняющие примеры.

4. В разделе «Проверка  программы» должны быть приведено  описание способов проверки, позволяющих  дать общее заключение о работоспособности  программы (контрольные примеры, методы прогона, результаты).

5. В разделе «Дополнительные  возможности» должно быть приведено  описание дополнительных разделов  функциональных возможностей программы  и способов их выбора.

6. В разделе «Сообщения  системному программисту» должны  быть указаны тексты сообщений, выдаваемых в ходе выполнения настройки, проверки программы, а также в ходе выполнения программы, описание их содержания и действий, которые необходимо предпринять по этим сообщениям.

7. В приложении к  руководству системного программиста могут быть приведены дополнительные материалы (примеры, иллюстрации, таблицы, графики и т.п.).

 

1.3 Требования, предъявляемые к  оформлению программных документов

Программная документация является неотъемлемым компонентом программного продукта и должна оформляться в соответствии с Единой системой программной документации (ЕСПД - ГОСТ серии 19). В рамках учебных работ допускается заключать всю содержательную часть программной документации в единый "отчёт по программе", при этом формальные требования к оформлению такого отчёта соответствуют требованиям к отчёту по НИР. В данном разделе изложены ключевые моменты государственных стандартов ЕСПД.

Программная документация, кроме формальных документов (спецификация, ведомость держателей подлинников, формуляр и др.), включает:

  • техническое задание (назначение, область применения программы, требования, предъявляемые к программе);
  • текст программы (запись программы с необходимыми комментариями);
  • описание программы (сведения о логической структуре и функционировании программы);
  • пояснительная записка (схема алгоритма, общее описание алгоритма и/или функционирования программы, обоснование принятых решений);
  • эксплуатационные документы.

Программный документ "Пояснительная  записка" составляется на стадии эскизного или технического проектов программы. Как правило, на стадии рабочего проекта не используется.

К эксплуатационным документам относят:

  • описание применения (сведения о назначении программы, области применения, применяемых методах, классе решаемых задач, ограничениях для применения, минимальной конфигурации технических средств);
  • руководство системного программиста (сведения для проверки, обеспечения функционирования и настройки программы на условия конкретного применения);
  • руководство программиста (сведения для эксплуатации программы);
  • руководство оператора (сведения для обеспечения общения оператора с вычислительной системой в процессе выполнения программы);
  • описание языка (описание синтаксиса и семантики языка);
  • руководство по техническому обслуживанию (сведения для применения тестовых и диагностических программ при обслуживании технических средств).

Основная часть программной  документации составляется на стадии рабочего проекта. Необходимость того или иного документа определяется на этапе составления технического задания. Допускается объединять отдельные виды документов.

Эксплуатационный документ "Описание языка" включается в  программную документацию, если разработанный  программный продукт реализует  некий язык программирования, управления заданиями, организации вычислительного процесса и т. п.

Эксплуатационный документ "Руководство по техническому обслуживанию" включается в программную документацию, если разработанный программный  продукт требует использования  тестовых или диагностических программ.

В техническое задание включают:

  • введение (наименование, краткая характеристика области применения программы);
  • основания для разработки (документы, на основании которых ведётся разработка, организация, утвердившая документы, дата утверждения, наименование и обозначение темы разработки);
  • назначение разработки (функциональное и эксплуатационное назначение программы);
  • требования к программе и программной документации;
  • технико-экономические показатели;
  • стадии и этапы разработки;
  • порядок контроля и приёмки.
  • Наиболее существенной частью технического задания является раздел "требования" В этом разделе приводятся:
  • требования к функциональным характеристикам (состав выполняемых функций, организация входных и выходных данных, временные характеристики);
  • требования к надёжности (обеспечение устойчивого функционирования, контроль входной и выходной информации, время восстановления после отказа);
  • требования к информационной и программной совместимости (требования к информационным структурам на входе и выходе, методам решения, исходным кодам, языкам программирования и программным средствам; требования к защите информации);
  • требования к составу и параметрам технических средств;
  • требования к программной документации.

Данный раздел может  содержать требования к маркировке, упаковке, транспортировке и хранению, а также условия эксплуатации.

Кроме явно описанных  в техническом задании требований, следует придерживаться общепринятых правил разработки программ с учётом выбранной парадигмы программирования:

  • программа не должна содержать избыточные элементы (все элементы программы адекватны поставленной задаче: нет циклов, массивов и т. п. элементов, без которых можно обойтись).
  • алгоритм должен быть структурирован: для функционального стиля программирования - адекватное разбиение на функции (процедуры), для объектно-ориентированного - адекватная иерархия классов. Каждая функция (метод класса) должна реализовывать ровно одно действие.
  • у функций (методов классов) должны быть параметры. Следует избегать использования в функциях глобальных переменных.
  • программа должна аккуратно использовать память: работать с динамическими массивами, в ней не должно быть неиспользуемых блоков памяти, лишних переменных.
  • должны проверятся диапазоны вводимых пользователем значений и параметров, передаваемых между модулями программы.
  • при использовании в программе каких-либо готовых компонент (библиотечных функций, классов) если функция или метод класса может завершиться неудачей, необходимо обязательно проверять это, не полагаясь на незначительность вероятности такого события.
  • программа должна быть конфигурируема (важные параметры программы следует выделить в единый блок).

1.4 Методы тестирования

ВОСХОДЯЩЕЕ ТЕСТИРОВАНИЕ

При восходящем подходе  программа собирается и тестируется  снизу вверх. Только модули самого  нижнего  уровня  («терминальные»  модули;  модули,  не вызывающие других модулей) тестируются изолированно, автономно.  После  того как тестирование этих  модулей  завершено,  вызов  их  должен быть так же надежен, как вызов встроенной функции языка или  оператор присваивания. Затем тестируются модули, непосредственно вызывающие уже проверенные. Эти модули более высокого уровня  тестируются не автономно, а вместе с уже проверенными модулями более низкого уровня. Процесс повторяется до тех  пор, пока не будет достигнута вершина. Здесь завершаются и тестирование модулей, и тестирование сопряжений программы.

При восходящем тестировании  для  каждого  модуля  необходим  драйвер: нужно подавать тесты в  соответствии с сопряжением тестируемого модуля.  Одно из возможных  решений  -  написать  для каждого модуля  небольшую ведущую программу. Тестовые данные представляются как «встроенные»  непосредственно в эту программу переменные и структуры данных, и она  многократно  вызывает тестируемый модуль, с каждым вызовом передавая ему  новые тестовые данные. Имеется и лучшее решение: воспользоваться программой тестирования модулей - это инструмент тестирования,  позволяющий описывать тесты на специальном языке и избавляющий от необходимости писать драйверы.

НИСХОДЯЩЕЕ ТЕСТИРОВАНИЕ

Нисходящее тестирование (называемое также нисходящей разработкой) не является полной противоположностью восходящему, но в первом приближении  может рассматриваться как  таковое. При нисходящем подходе программа  собирается и тестируется сверху вниз. Изолировано  тестируется только головной модуль. После того как тестирование этого модуля завершено, с ним соединяются (например, редактором связей) один за другим модули, непосредственно вызываемые им, и тестируется полученная комбинация. Процесс повторяется до тех пор, пока не будут собраны и проверены все модули.

При этом подходе немедленно возникает два вопроса: что делать, когда тестируемый модуль вызывает модуль более низкого уровня (которого в данный момент еще не существует), и как подаются тестовые данные. Ответ на первый вопрос состоит в том, что для имитации функций недостающих модулей программируются модули-заглушки», которые моделируют функции отсутствующих модулей. Фраза «просто напишите заглушку» часто встречается в описании этого подхода, но она способна ввести в заблуждение, поскольку задача написания заглушки» может оказаться трудной. Ведь заглушка редко сводится просто к оператору RETURN, поскольку вызывающий модуль обычно ожидает от нее выходных параметров. В таких случаях в заглушку встраивают фиксированные выходные данные, которые она всегда и возвращает. Это иногда оказывается неприемлемым, так как вызывающий модуль может рассчитывать, что результат вызова зависит от входных данных. Поэтому в некоторых случаях заглушка должна быть довольно изощренной, приближаясь по сложности к модулю, который она пытается моделировать.

Преимуществом нисходящего  подхода очень часто считают  отсутствие необходимости в драйверах; вместо драйверов вам просто следует  написать «заглушки». Как читатель сейчас уже, вероятно, понимает, это преимущество спорно.

Нисходящий метод тестирования имеет, к сожалению, некоторые недостатки. Основным из них является тот, что  модуль редко тестируется досконально  сразу после его  подключения. Дело в том, что основательное тестирование некоторых модулей может потребовать крайне изощренных заглушек. Программист часто решает не тратить массу времени на их программирование, а вместо этого пишет простые заглушки и проверяет лишь часть условий в модуле. Он, конечно, собирается вернуться и закончить тестирование рассматриваемого модуля позже, когда уберет заглушки. Такой план тестирования определенно не лучшее решение, поскольку об отложенных условиях часто забывают.

Второй тонкий недостаток нисходящего подхода состоит  в том, что он может породить веру в возможность начать программирование и тестирование верхнего уровня программы до того, как вся программа будет полностью спроектирована. Эта идея на первый взгляд кажется экономичной, но обычно дело обстоит совсем наоборот. Большинство опытных проектировщиков признает, что проектирование программы - процесс итеративный. Редко первый проект оказывается совершенным. Нормальный стиль проектирования структуры программы предполагает по окончании проектирования нижних уровней вернуться назад и подправить верхний уровень, внеся в него некоторые усовершенствования или исправляя ошибки, либо иногда даже выбросить проект и начать все сначала, потому что разработчик внезапно увидел лучший подход.

Если же головная часть  программы уже запрограммирована и оттестирована, то возникает серьезное сопротивление любым улучшениям ее структуры. В конечном итоге за счет таких улучшений обычно можно сэкономить больше, чем те несколько дней или недель, которые рассчитывает выиграть проектировщик, приступая к программированию слишком рано.

 

1.5 Тестирование программы

Тестирование программного обеспечения

Существует несколько  признаков, по которым принято производить  классификацию видов тестирования. Обычно выделяют следующие:

По объекту тестирования:

  • Функциональное тестирование
  • Тестирование производительности
  • Нагрузочное тестирование
  • Стресс - тестирование
  • Тестирование стабильности
  • Тестирование удобства использования
  • Тестирование интерфейса пользователя
  • Тестирование безопасности
  • Тестирование локализации
  • Тестирование совместимости

По знанию системы:

  • Тестирование чёрного ящика
  • Тестирование белого ящика
  • Тестирование серого ящика

По степени автоматизации:

  • Ручное тестирование
  • Автоматизированное тестирование
  • Полу автоматизированное тестирование

По степени изолированности  компонентов:

  • Компонентное (модульное) тестирование
  • Интеграционное тестирование
  • Системное тестирование

По времени проведения тестирования:

  • Альфа - тестирование:
  • Тестирование при приёмке
  • Тестирование новой функциональности
  • Регрессионное тестирование
  • Тестирование при сдаче
  • Бета - тестирование

По признаку позитивности сценариев:

  • Позитивное тестирование
  • Негативное тестирование

По степени подготовленности к тестированию:

  • Тестирование по документации
  • ad hoc тестирование или интуитивное тестирование

Уровни тестирования

  •  Модульное тестирование (юнит - тестирование) - тестируется минимально возможный для тестирования компонент, например, отдельный класс или функция. Часто модульное тестирование осуществляется разработчиками ПО.
  • Интеграционное тестирование - тестируются интерфейсы между компонентами, подсистемами. При наличии резерва времени на данной стадии тестирование ведётся итерационно, с постепенным подключением последующих подсистем.
  • Системное тестирование - тестируется интегрированная система на её соответствие требованиям.
  • Альфа - тестирование - имитация реальной работы с системой штатными разработчиками, либо реальная работа с системой потенциальными пользователями / заказчиком. Чаще всего альфа - тестирование проводится на ранней стадии разработки продукта, но в некоторых случаях может применяться для законченного продукта в качестве внутреннего приёмочного тестирования. Иногда альфа-тестирование выполняется под отладчиком или с использованием окружения, которое помогает быстро выявлять найденные ошибки. Обнаруженные ошибки могут быть переданы тестировщикам для дополнительного исследования в окружении, подобном тому, в котором будет использоваться ПО.
  • Бета - тестирование - в некоторых случаях выполняется распространение версии с ограничениями (по функциональности или времени работы) для некоторой группы лиц, с тем, чтобы убедиться, что продукт содержит достаточно мало ошибок. Иногда бета-тестирование выполняется для того, чтобы получить обратную связь о продукте от его будущих пользователей.

Часто для свободного/открытого  ПО стадия альфа - тестирования характеризует функциональное наполнение кода, а бета - тестирования - стадию исправления ошибок. При этом, как правило, на каждом этапе разработки промежуточные результаты работы доступны конечным пользователям.

Статическое и динамическое тестирование

Описанные выше техники - тестирование белого ящика и тестирование чёрного ящика - предполагают, что код исполняется, и разница состоит лишь в той информации, которой владеет тестировщик. В обоих случаях это динамическое тестирование.

Разработка программного продукта при моделировании экологических систем