Отправляет email-рассылки с помощью сервиса Sendsay

Всё о работе в Интернет

  Все выпуски  

Занятие 47. Какая программа может считаться правильной? Отладка и тестирование программ. Тестирование подпрограмм с помощью таблиц исполнения.


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

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

КОНТРОЛЬ ПРАВИЛЬНОСТИ АЛГОРИТМОВ И ПРОГРАММ

1. Какая программа может считаться правильной?

Предположим, что мы назвали правильной ту программу, которая для всех наборов допустимых значений исходных данных даёт правильные результаты. Однако, такое определение не конструктивно по той простой причине, что практически невозможно построить и опробовать абсолютно все наборы допустимых значений исходных данных. И тем более невозможно каким-то иным образом найти абсолютно все правильные результаты, чтобы сравнить их с теми, которые получатся в результате применения программы.

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

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

Разумеется, правильные результаты, используемые для сравнения, должны быть получены каким-то иным путём.

Рассмотренный подход к оценке качества программы практически доступен, но полных гарантий не даёт.

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

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

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

2. Отладка и тестирование программ.

В процессе проведения отладки в тексте написанной программы могут обнаруживаться ошибки трёх основных видов:

-       синтаксические ошибки;

-       ошибки времени выполнения;

-       алгоритмические ошибки.

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

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

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

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

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

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

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

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

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

3. Тестирование подпрограмм с помощью таблиц исполнения.

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

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

Таблица исполнения подпрограммы – прямоугольная.

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

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

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

С целью тщательного тестирования подпрограммы таких таблиц исполнения может быть построено несколько для разных контрольных примеров.

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

Для эффективной работы с таблицей исполнения необходимо досконально знать правила исполнения операторов языка Паскаль. Чтобы таблица исполнения подпрограммы была понятной и однозначной, при записи в неё значений переменных и условий следует неукоснительно придерживаться следующего правила: каждое очередное значение должно заноситься только правее всех предыдущих в текущую строку или ниже всех предыдущих в следующую строку. Иначе говоря, последовательность заполнения и анализа таблицы исполнения устанавливается строго в направлении “слева – направо – вниз”.

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

Пример. Построим таблицу исполнения подпрограммы вычисления суммы факториалов натуральных чисел от 1 до N.

   Function Sum_Fact ( N: LongInt ): LongInt;
      Var i,F,S: LongInt;
   Begin
      F := 1; S := 0;
      For i:=1 To N Do Begin
         F := F * i; S := S + F End;
      Sum_Fact := S
   End;

Дано: N = 3. Результат: Sum_Fact = 1! + 2! + 3! = 9.

 

F

S

i

i <= N

 

a

b

c

d

a

1

0

1

True

b

1

1

2

True

c

2

3

3

True

d

6

9

4

False

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

В таблицу исполнения включены переменные подпрограммы i, F, S, а также неявно проверяемое условие продолжения выполнения оператора арифметического цикла i<=N. Сама переменная N в таблицу не включена, поскольку её значение в процессе выполнения подпрограммы  изменяться не будет.

Сначала выполняются два первых оператора присваивания (значение 1 в ячейке a-a и значение 0 в ячейке a-b).

Очередной оператор – оператор арифметического цикла. Параметру i присваивается начальное значение (значение 1 в ячейке a-c). Затем осуществляется проверка условия продолжения цикла i<=N (значение 13, равное True, в ячейке a-d).

Поскольку проверенное условие оказалось истинным, должны быть выполнен цикл. Первый оператор присваивания в составе цикла образует новое значение переменной F (значение 1 в ячейке b-a) в результате перемножения переменных F (значение 1 в ячейке a-a) и i (значение 1 в ячейке a-c). Второй оператор присваивания в составе цикла образует новое значение переменной S (значение 1 в ячейке b-b) в результате сложения переменных S (значение 0 в ячейке a-b) и F (значение 1 в ячейке b-a).

Далее значение параметра цикла i автоматически увеличивается на единицу (значение 2 в ячейке b-c) и осуществляется возврат на проверку условия i<=N (значение 23, равное True, в ячейке b-d).

Снова выполняются операторы в составе цикла. В результате переменные F и S приобретают новые значения (значения 2 и 3 в ячейках c-a и c-b соответственно). Автоматически увеличивается значение параметра цикла (значение 3 в ячейке c-c). Проверяется условие i<=N (значение 33, равное True, в ячейке c-d).

Операторы в составе цикла выполняются третий раз подряд. Получает новое значение переменная F (значение 6 в ячейке d-a), а также переменная S (значение 9 в ячейке d-b). После увеличения значения параметра цикла (значение 4 в ячейке d-c) и проверки условия i<=N (значение 43, равное False, в ячейке d-d) выясняется, что выполнение оператора арифметического цикла можно прекратить.

Последний оператор подпрограммы – оператор присваивания. С его помощью значение результата, равное 9, присваивается функции Sum_Fact. Исполнение подпрограммы закончено.

Уважаемые подписчики! При необходимости задать вопрос, проконсультироваться, уточнить или обсудить что-либо обращайтесь через Гостевую книгу моего персонального сайта http://a-morgun.narod.ru. При этом настоятельно рекомендую пользоваться браузером Internet Explorer.

С уважением, Александр.


В избранное