Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Курсовой - Специфицирование и тестирование программ.doc
Скачиваний:
57
Добавлен:
02.05.2014
Размер:
125.95 Кб
Скачать

1 Краткие теоретические сведения

1.1 Внешние спецификации программного обеспечения

1.1.1 Структурирование целей разрабатываемого программного обеспечения

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

Структурным анализом принято называть такое исследование системы, которое начинается с ее общего обзора и затем детализируется, приобретая иерархическую структуру со все большим числом уровней /4/. Для таких методов характерно разбиение на уровни абстракции с ограничением числа элементов на каждом из уровней (обычно от 3 до 6-7). В технологии программирования эта идея была сформулирована как один из принципов структурного программирования: разработку программ рекомендуется вести сверху вниз или, иначе, по нисходящей стратегии.

Суть нисходящей стратегии в том, что цели разрабатываемого ПП структурируются по схеме: цели - подцели 1-го уровня - ... - подцели i-го уровня - ... - подцелиn-уровня - функции до такой степени детализации, когда реализация подцелей последнего уровня (функций) становится очевидной.

Для примера рассмотрим функционирование банкомата при обслуживании клиента по его кредитной карте /4/. Цель верхнего уровня‘обслужить клиента’включает такие подцели:

а) получить пароль,

б) получить запрос на обслуживание,

в) обработать запрос на обслуживание,

г) обработать кредитную карту.

Подцели ‘а’,‘б’и‘г’не требуют дальнейшей детализации, а подцель‘в’не является столь очевидной и требуется ее структурирование на подцели следующего уровня. Этими подцелями будут:

  1. обработать внутреннюю банковскую документацию;

  2. распечатать баланс клиента;

  3. распечатать операцию клиента ( уведомление о проведенной операции);

  4. подготовить деньги клиента.

Окончательная структура целей для рассматриваемого примера приведена на рисунке 1.1.

обслужить

получить получить обработать обработать

пароль запрос на запрос карту

обслужив.

обработать распечатать распечатать подготовить

документа- баланс операцию деньги

цию клиента клиента клиенту

Рисунок 1.1

1.1.2 Спецификация функций с помощью таблиц решений

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

На следующем этапе составляются внешние спецификации выявленных функций или, иначе, спецификации процессов. Фактически спецификации являются описаниями алгоритмов соответствующих функций. Для этих целей существует достаточно много методов, которые перечислим в порядке увеличения трудности проектирования алгоритмов /4/:

- текстовое описание,

- структурированный естественный язык,

- таблица решений,

- дерево решений,

- визуальный язык,

- блок-схема,

- язык программирования.

Следует отметить, что в перечисленном выше порядке увеличивается степень формализации описания алгоритма и понимание деталей его функционирования проектировщиками и программистами, но уменьшается степень понимания алгоритма заказчиком и будущим пользователем ПО, для которого оно разрабатывается. Компромиссным решением проблемы понимания являются методы алгоритмизации, лежащие в середине спектра методов. Рассмотрим подробнее таблицу решений как вариант этого компромисса /4/.

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

ТР состоит из двух частей. Верхняя часть таблицы используется для определения условий. Обычно условие является ЕСЛИ-частью оператора ЕСЛИ-ТО и требует ответа ‘да-нет’. Нижняя часть ТР используется для определения действий, т.е. ТО-части оператора ЕСЛИ-ТО. Левая часть ТР содержит собственно описание условий и действий, а в правой части перечисляются все возможные комбинации условий и, соответственно, указывается, какие конкретно действия и в какой последовательности выполняются, когда определенная комбинация условий имеет место.

Поясним сказанное на примере спецификации процесса выбора символов из входного потока по следующим правилам:

а) если очередной символ является управляющим, то подать звуковой сигнал и вернуть код ошибки;

б) если буфер формируемой строки заполнен, то подать звуковой сигнал и вернуть код ошибки;

в) если очередной символ не находится в заданном диапазоне, (положим, от ‘а’до‘я’), то подать звуковой сигнал и вернуть код ошибки;

г) иначе поместить символ в буфер, увеличить значение счетчика выбранных символов и вернуть новое значение счетчика.

Таблица решений для данного примера приведена ниже ( таблица 1.1).

Здесь ‘Д’означает‘да’,‘Н’-‘нет’, 1,2 - помеченные действия выполняются в указанном порядке.

Таблица 1.1 - ТР для функции выбора символов из входного потока

Условия

1

2

3

4

5

6

7

8

С1 символ управляющий?

Д

Д

Д

Д

Н

Н

Н

Н

С2 буфер заполнен?

Д

Д

Н

Н

Д

Д

Н

Н

С3 символ от ‘a’ до’я’?

Д

Н

Д

Н

Д

Н

Д

Н

Действия

D1 подать звуковой сигнал

1

1

1

1

1

1

1

D2вернуть код ошибки (>0)

2

2

2

2

2

2

2

D3увеличить значение счетчика и вернуть его

2

D4поместить символ в буфер

1

Заметим, что если выполняется условие С1, то нет необходимости в проверке условий С2 и С3. Поэтому комбинации условий 1,2,3,4 могут быть заменены обобщающей комбинацией (Д, -, -), где‘-’означает любую из возможных альтернатив (в данном случае Д или Н). Аналогично комбинации условий 5 и 6 могут быть заменены обобщающей комбинацией (Н, Д, -). Редуцированная таким образом ТР будет иметь вид таблицы 1.2.

Таблица 1.2 Редуцированная ТР

Условия

1

2

3

4

С1 символ управляющий?

Д

Н

Н

Н

С2 буфер заполнен?

-

Д

Н

Н

С3 символ от ‘a’ до’я’?

-

-

Д

Н

Действия

D1 подать звуковой сигнал

1

1

1

D2вернуть код ошибки (>0)

2

2

2

D3увеличить значение счетчика и вернуть его

2

D4поместить символ в буфер

1

Методика построения ТР заключается в следующем:

а) определить все условия и действия в спецификации;

б) вписать действия и условия в таблицу;

в) в нумерованных столбцах отметить все возможные комбинации условий и выполняемых при выполнении условий действий;

г) при необходимости редуцировать таблицу (если есть 2 столбца, у которых перечень действий совпадает и которые отличаются только результатами условий ‘Д’и‘Н’в одной строке, то такие столбцы могут быть слиты в один).

Отметим, что на основе ТР легко осуществить кодирование программы на языке высокого уровня, таком , как Pascal.

1.2 Стратегии тестирования

Тестирование программного обеспечения охватывает целый ряд видов деятельности, аналогичных последовательности процессов разработки программного обеспечения. В него входят /2/ :

а) постановка задачи для теста,

б) проектирование теста,

в) написание тестов,

г) тестирование тестов,

д) выполнение тестов,

е) изучение результатов тестирования.

Решающую роль играет проектирование тестов. Возможен целый ряд подходов к стратегии проектирования тестов. Чтобы ориентироваться в них, рассмотрим два крайних подхода /5/. Первый состоит в том, что тесты проектируются на основе внешних спецификаций программ и модулей либо спецификаций сопряжения программы или модуля. Программа при этом рассматривается как черный ящик (стратегия‘черного ящика’). Существо такого подхода - проверить, соответствует ли программа внешним спецификациям. При этом логика модуля совершенно не принимается во внимание.

Второй подход основан на анализе логики программы (стратегия ‘белого ящика’). Существо подхода - в проверке каждого пути, каждой ветви алгоритма. При этом внешняя спецификация во внимание не принимается.

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

Проанализируем теперь второй подход к тестированию. На рисунке 2.1 изображены возможные пути небольшого программного модуля /2/.

Рисунок 1.2

Квадратами представлены последовательные сегменты, а стрелками - передачи управления (с помощью развилок или циклов). Число путей в модуле имеет порядок (для сравнения, возраст вселенной в секундах оценивается как 4´). Но даже если предположить, что выполнены тесты для всехпутей, можно утверждать, что модуль удовлетворительно не протестирован.

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

IF (A+B+C)/3=A,

то оно будет верным не для всех значений A, B и С (ошибка возникает в том случае, когда из двух значений В или С одно больше, а другое на столько же меньше А). Если концентрировать внимание только на тестировании путей, нет гарантии, что эта ошибка будет выявлена.

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

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

Рекомендуется следующая процедура разработки тестов: - разрабатывать тесты, используя методы стратегии “черного ящика”; - дополнительное тестирование, используя методы стратегии “белого ящика”.

1.3 Метод тестирования таблиц решений

Одним из методов тестирования программ по стратегии ‘черного ящика’является метод функциональных диаграмм. Он хорошо вписывается в методы структурного анализа, реализующиеся в современныхCASE-средствах разработки программного обеспечения. Этот метод излагается в /2/, требует предварительного изучения методики построения функциональных диаграмм, в силу чего является достаточно сложным для начинающих программистов. Однако интерес представляет тот факт, что метод сводится к получению в качестве промежуточного результата таблицы решений и составления тестов по этой таблице. Некоторые методики структурного анализа также включают тестирование спецификаций, полученных методами, обладающими недостаточными процедурными возможностями (они перечислены первыми среди методов специфицирования процессов в пункте 1.2.).

Тестирование ТР заключается в том, что проектируется такое количество тестов, которое позволяет покрыть все возможные комбинации условий. Как правило, количество этих тестов совпадает с числом столбцов в ТР. Так, для рассмотренного в пункте 1.1.2 примера выбора символов из входного потока (см. таблицу 1.2) необходимо реализовать 4 теста:

а) символ из входного потока является управляющим;

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

в) во входном потоке символов меньше, чем вмещает буфер формируемой строки, среди них нет управляющих символов, но присутствуют символы, не входящие в диапазон от ‘а’до‘я’;

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

Положим, что управляющими символами являются ‘! & *’и пусть буфер формируемой строки рассчитан на 10 символов. Тогда соответствующие тесты могут быть:

а) &

б) а б в г д е ж з и к л м

в) а б 1 в г 5 д

г) а б в г д е ж з и .

Ожидаемыми результатами тестирования являются:

а) звуковой сигнал и отличный от нуля код ошибки;

б) звуковой сигнал и отличный от нуля код ошибки;

в) звуковой сигнал и отличный от нуля код ошибки;

г) отсутствие звукового сигнала и равный нулю код ошибки.

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