
5. Тестирование.
Тестирование может быть автономным (по частям) и комплексным (целиком).
Критерии, предъявляемые на этапе тестирования:
Каждый оператор должен быть выполнен, по крайней мере, один раз, и программа должна выдать правильный результат;
Каждая ветвь программы должна быть опробована;
Каждый путь программы должен быть испытан хотя бы один раз с использованием всего набора тестовых данных;
Для каждой спецификации программы необходимо располагать набором тестовых данных, позволяющим установить, что программа правильно реализует данную спецификацию.
Производятся испытание системы, ее верификация, определяется правильность и надежность программы, ее «живучесть».
Лекция № 3
Определение спецификации
Процесс построения функциональной спецификации может быть разделен на два этапа: нисходящий анализ и восходящее реструктурирование. На нисходящем этапе сложная система представляется в виде иерархической совокупности подсистем, описанных на языке SDL. Каждая подсистема является объединением потока команд и потока данных и может рассматриваться независимо для целей проектирования, оптимизации и т.д. Затем, на восходящем этапе, они локально или глобально реструктурируются для получения новой структуры, реализующий заданный критерий оптимальности (например, максимальный параллелизм). При этом общая функциональность системы и целевая функция сохраняются, а видоизменяется структура, становясь наиболее оптимальной в соответствии с заданным критерием.
Наиболее производительными системами являются системы с использованием максимального параллелизма. Однако если все процессы будут протекать параллельно, то нарушится принцип детерминированности системы, достоверность ее работы: начнутся параллельно те процессы, которые принципиально требуют данных после завершения предыдущего, и неизвестно, какие данные будут приняты для нового процесса.
Общий метод
Модульный подход является одним из ключевых при построении функциональной структуры на этапе спецификации системы. Существуют три типа модульных методов: методы потока команд, при которых модули выполняются в последовательной командной среде; методы потока данных, при которых модули связываются последовательными потоками данных; объединение этих двух методов, при котором поток команд и поток данных взаимодействуют и дополняют друг друга.
Набор функций, который должна выполнить система, задан изначально, а в самой структуре «живут» модули («жить» они начинают после программирования задачи, когда система уже может работать в реальном мире). Каждый модуль реализует какую-нибудь функцию, он может быть представлен как черный ящик с входом и выходом.
Одной из принципиальных черт объединенной графовой модели является явное разделение графов управления и графов данных. Но эта модель не перестает быть объединенной: оба потока проходят через одни и те же вершины – функциональные модули.
Граф управления всегда начинается одной входной вершиной, называемой ‘START’, и оканчивается одной выходной вершиной, называемой ‘END’. Граф определяет поток команд через последовательность модулей с точки зрения временных интервалов.
Граф данных определяет для каждого модуля требования по данным, т.е. взаимодействия между данными и модулями с точки зрения пространства.
Объединенная графовая модель является графическим представлением информационно-алгоритмической модели, в которой поток данных (граф данных) отвечает за информационную основу модели, а поток команд (граф управления) – за алгоритмическую. Данная модель показывает, в какой последовательности выполняется система.
Модуль может быть определен как fm(A,B,...)= (C,D,...). Это означает, что входные данные (A,B,...), называемые областью, обрабатываются модулем m и результаты сохраняются в (C,D,...), называемой противообластью. Отдельный модуль может различаться по сложности от простого оператора, вроде оператора сложения, до вычислительного элемента произвольной сложности, такого как микропроцессор.
Использование модуля определенного уровня сложности определяется целью поставленной задачи. Например, быстрое преобразование Фурье. В данном случае само преобразование рядов Фурье и является функциональным модулем. Он может быть представлен как программа (используется для ядерных реакций) или как микропроцессор (например, для определения доплеровского сдвига), производящий преобразование очень быстро.
Каждый модуль связан через свою область и противообласть с графом данных. Входные и выходные могут варьироваться от файла и периферийного устройства до регистра и ячейки памяти. В качестве периферийных устройств могут быть: АЦП в PCI шине, АЦП на USB порту, микрофон (при взрывных экспериментах). Несколько асинхронных действий в графе управления могут проходить одновременно через поток команд с различными скоростями, определяемыми временными задержками модулей, причем циклы не допустимы. Любая функция выполняется во времени, а каждый модуль имеет некоторое время задержки, даже если это время стремится к нулю. Ввиду невозможности возвращения во времени назад в графе управления циклов существовать не может.
Каждый модуль должен лежать на пути от вершины START до вершины END. С другой стороны, в графе данных область может использоваться в качестве противообластей для своего собственного модуля, так что графы данных могут быть цикличными и несвязными. Два графа взаимосвязаны, точно описывая функциональную структуру соответствующей системы. Подчеркнем тот факт, что модуль может действовать, только если он запущен графом управления, т.к. модуль существует во временной командной среде. Области и противообласти, кроме работы в качестве входа и выхода для модулей, могут быть непосредственно прочитаны из графа управления.
Пример:
Рассмотрим следующие вычисления:(a+jb)*(c+jd)=(a*c - b*d)+j(b*c + a*d)=x+jy Здесь вычисляется комплексное число (x+jy) из двух комплексных чисел (a+jb) и (c+jd) путем их умножения и записи действительной и мнимой частей в ‘x’ и ‘y’. a, b, c и d записываются в ‘a’, ‘b’, ‘c’ и ‘d’ соответственно. Используя четыре умножителя мы можем выполнить вычисление умножений параллельно, но умножения в каждом выражении должны быть завершены до сложения и вычитания, т.е. мы имеем порядок вычисления, показанный на рис.1. Соответствующий граф данных и граф управления показаны на рис.2.
Рис.1. Порядок вычисления
а) б)
Рис. 2. Пара графов:
а) - граф данных б) - граф управления
Граф данных. Есть четыре области, в которых лежат a, b, c и d. Это области, данные из которых запрашиваются модулем. Например, модуль m2 берет данные из областей b и d и помещает в противообласть р2.
Каждому модулю присваивается свой идентификатор (m1, m2, m3 и m4), несмотря на то, что функция умножения одна. Это связано с тем, что области m1 отличаются от областей m2 и т.д. А если входные данные у модуля разные (различные пользователи), то модули также различны, хотя программа (или процедура, или устройство), их выполняющая, одна.
Граф управления показывает, в каком порядке могут выполняться операции. В этом графе модуль срабатывает и исходные данные преобразует в выходные только тогда, когда ему отдано управление.
Путь от модуля ‘m1’ до модуля ‘sub’ предполагает, что умножение m1 (a*c —> p1) должно произойти до вычитания (p1-p2 —> x). Пути между ‘m1’ и ‘add’ не существует и, так как порядок запуска этих операций несущественен, они могут выполняться параллельно. Лучшей рабочей последовательностью является m1, m2, m3 и m4 параллельно и, после окончания m1 и m2 запускается ‘sub’; после окончания m3 и m4 запускается ‘add’.
Для того, чтобы сделать объединенную модель применимой как для аппаратуры так и для программного обеспечения, она должна быть способна моделировать рекурсию. Тот факт, программные фрагменты с функцией OR или циклами могут привести к циклическим графам, сделает процесс определения детерминированности более сложным. Чтобы избежать явных циклов в графе управления, имеется три проверочных модуля. Это модуль повторения WHILE, условный модуль IF и модуль выбора SWITCH. Каждый имеет один или более подграфов. Функция модулей IF и SWITCH состоит в том, что “согласно проверочному условию идти на соответствующий подграф”. Функция модуля WHILE состоит в том, что “если значение true, выполняется подграф do; когда подграф завершен проверить условие снова и, если оно true то повторить; как только проверка не проходит модуль WHILE завершает свою работу. Подграфом является либо отдельный модуль, либо набор связанных модулей с собственным STARTом и собственным ENDом. Вход в подграф может быть только через START к соответствующему END. Граф данных не имеет подграфов как таковых, но модули подграфов графа управления ссылаются на граф данных, и, также, могут быть распространены на более низкий уровень. Условие проверки, заданное в модуле проверки, рассматриваем как простое сравнение, которое может включать области, противообласти, константы и операторы сравнения (<, =, >, <=, == и >=). Именно эта способность модулей проверки явно проверять величины данных из графа данных позволяет моделировать сложные системы.