На этапе отладки программы. Тестирование и отладка программного обеспечения. Тестирование и отладка программы

Отладка программы – это деятельность, направленная на обнаружение и исправление ошибок в программе. Обнаружить ошибки, связанные с нарушением правил записи программы на языке программирования (синтаксические и семантические ошибки), помогает используемая система программирования. Пользователь получает сообщение об ошибке, исправляет ее и снова повторяет попытку исполнить программу.

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

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

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

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

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

Всю документацию можно разбить на две группы:

– документы управления разработкой ПС;

– документы, входящие в состав ПС.

Документы управления разработкой ПС протоколируют процессы разработки и сопровождения ПС, обеспечивая связи внутри коллектива разработчиков и между коллективом разработчиков и менеджерами – лицами, управляющими разработкой.

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

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

Контрольные вопросы

1. Что такое система программирования?

2. Что относится к технологии OLE?

3. Что относится к технологии Microsoft .NET?

4. Что такое модульное программирование?

5. Назовите основные принципы объектно-ориентрованного программирования.

6. Что относится к процедурному программированию?

7. Как происходит отладка и тестирование программ?

8. Какие виды документации используют при разработке программ?

9. Что такое парадигма программирования?

10. Что такое объекты, классы?

Начинается самый трудоемкий и, в профессиональном плане, самый сложный этап разработки приложения – ОТЛАДКА ПРОГРАММЫ. Сложно написать программу сразу без ошибок. И при этом ошибки бывают разные как по природе из возникновения, так и по трудоемкости исправления.

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

Более сложные ошибки – ошибки ВЫПОЛНЕНИЯ ПРОГРАММЫ. Они проявляются только во время работы программы. Вот ими мы и займемся.

Запуск программы на выполнение

Запустить программу в VBA можно несколькими путями.

Запуск через главное меню приложения – самый длинный, но и в то же время, самый типовой прием. Перейдите на лист EXCEL, наберите на чистом листе табличку рисунок 11а, выделите ее как блок (либо мышкой, либо другим путем), поскольку наша программа начнет свою работу с поиска выделенного блока.

Войдите в меню СЕРВИС-МАКРОС-МАКРОСЫ (или Alt+F8) и вы получите окно со списками всех программных модулей (макросов), какие есть сейчас у Вас в приложении (рисунок 13). В нашем случае виден только один макрос – это наша подпрограмма Poradok. Установите на нее курсор и нажмите кнопку ВЫПОЛНИТЬ.

Миг и наша таблица на экране превращается в нечто, следующего вида:


Что-то это не похоже на нужную нам сортировку.

Половина начальных цифр исчезла, появились пустые клетки… Значит где-то в нашей программе «дыра». И может быть не одна. Ну что же, приступим, как говорят хирурги, беря в руки скальпель.

Инструменты отладки программ в vba.

Во-первых снова восстановим на листе EXCEL исходную таблицу рисунок 11а и выделим ее блоком. После этого клавишами Alt+F11 перейдем в инструментальную среду программирования VBA (ИС VBA).

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

Для запуска программы нажмем кнопку запуска приложения , расположенную в инструментальной линейке ИС VBA вверху экрана. Приложение запустится сразу, если ИС VBA разобралась в обстановке, или опять появится окно рисунок 13, если ИС VBA требуются пояснения, что же все-таки следует запустить. После запуска практически сразу программа остановится на нашей «точке останова», что будет видно по ярко желтой полосе на тексте программы. Теперь мы можем проанализировать ситуацию, создавшуюся в программе в текущему моменту. Для анализа раскроем окно локальных переменных (см. выше) и в нем, как в окне системного ПРОВОДНИКА откроем содержимое компонентов массива Mass (рисунок 14).

Видно, что к моменту, когда все данные с экрана должны быть перенесены в этот массив, на самом деле элемент Mass(1,1) – пустой, Mass(1,2) – тоже пустой, а элемент Mass(1,2) содержит 5, хотя должен содержать (см.рисунок 11а) – 8. Значит что-то не в порядке с циклом переноса данных в массив Mass. Анализируем его и видим, что в строке

Mass(i, j) = Cells(X + i, Y + j - 1)

при наборе текста программы мы пропустили -1 в первом индексе ячейки. Исправим эту ошибку:

Mass(i, j) = Cells(X + i - 1, Y + j - 1)

Остановим работу программы кнопкойв инструментальной линейке ИС VBA и снова запустим кнопкой. Теперь содержимое массива Mass в окне локальных переменных (рисунок 15) соответствует действительности.

Пока программа находится в состоянии останова, проверим также содержимое переменных X, Y, H и W. Их можно тоже посмотреть в окне локальных переменных, либо на них можно просто навести курсор мыши в любом месте текста программы и на секунду задержать его. ИС VBA тут же покажет небольшое окошко с содержимым указанной переменной (рисунок 16). Посмотрев все переменные убеждаемся, что блок ввода данных отработал нормально и во всех ячейках разместил именно те числа, которые должны быть.

П

Рисунок 17

родолжим выполнение программы и посмотрим, как она переставит числа теперь. Для продолжения нажмем кнопку. Программа быстро завершилась, что видно по очистке окна локальных переменных (после завершения программы все переменные уходят из поля видимости ИС VBA). Чтобы посмотреть результат переключимся на лист EXCEL. Видим таблицу рисунок 17. Чувство радости при внимательном рассмотрении таблицы сменяется унынием. Перестановка произошла, но как-то не до конца. В частности цифра 1 оказалась после цифры 5. Значит где-то еще «дыра». И скорее всего в блоке перестановки данных. Что ж, продолжим операцию отладки.

Опять придется восстановить таблицу на листе EXCEL в исходное состояние и выделить ее блоком. Снова переключимся в ИС VBA и запустим программу.

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

Если вы откроете меню ОТЛАДКА в верхней строке ИС VBA, то увидите, что режимов пошаговой отладки три. Они вызываются горячими клавишами F8, Shift+F8 и Ctrl+Shift+F8. Названия режимов написаны там же в меню. Нам нужен первый режим: «с заходом» в каждый оператор программы. Поэтому закрываем меню и нажимаем F8. Программа выполнила следующий оператор и остановилась. Теперь Вы можете проанализировать содержимое всех переменных в программе и оценить правильность хода выполнения программы. Снова нажимаете F8 и снова анализ. И так до тех пор пока не выявите ошибку или пока не закончится программа.

Предположим, что произошло второе, а мы так и не заметили где же наша программа ошибается. Тогда немного изменим технологию контроля за ходом выполнения программы. В циклах перестановки в нашей программе сравниваются всего пара ячеек Mass(i,j) и Mass(K,M). Настроим ИС VBA так, чтобы она показывала нам именно эти сравниваемые величины и индексы K и M, целевой ячейки (индексы i, j настольно просто изменяются, что ошибиться в них невозможно (почти)).

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

Здесь можно откорректировать (или вписать другое) переменную или выражение, которое Вы хотите контролировать и установить тип контроля. В нашем случае тип контроля – контрольное выражение. После нажатия на кнопку ОК, заказанное выражение попадает в окно контрольных значений. Вводим в окно все четыре интересующие нас величины.

Снова восстанавливаем таблицу на листе EXCEL в исходное состояние, выделяем ее блоком. Снова переключаемся в ИС VBA и запускаем программу. Снова, после останова программы, жмем F8, пошагово проходя по каждому оператору и анализируя изменение контрольных значений наших переменных (рисунок 18). И в какой-то момент с удивлением замечаем, что когда на следующем шаге индекс M должен был приобрести значение 1, этого не произошло. Внимательно посмотрев на текст программы, мы наконец замечаем, что пропустили оператор установки переменной L в 1.

Остановим программу. Добавим пропущенный оператор. Снова восстанавливаем таблицу на листе EXCEL в исходное состояние, выделяем ее блоком. Снова переключаемся в ИС VBA. Снимаем точку останова на операторе

For i = 1 To H

(щелчком мыши на нем) и запускаем программу.

Проверяем результат на листе EXCEL:

Ура! Наконец программа выдала то, что нам надо.

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

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

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

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

Код программы, который использует эти функции и удобен для нас выглядит так:

If VarType(obmen) > 1 And VarType(obmen) < 6 Then

Mass(i, j) = obmen

MsgBox "В ячейке "+Chr(Y + i + 63)+LTrim(Str(X + i - 1))+ _

" НЕ числовые данные"

Выводимый на экран текст в функции MsgBox составлен путем сложения отдельных фраз и номеров строки и столбца преобразованных в текст. С помощью стандартной функции языка Basic – Chr код столбца преобразовывается в букву его названия (но при этом, чтобы получилась буква к коду добавляется число 63 – смещение буква А в кодовой таблице символов).

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

Последнее требование к программе было – «снять выделение после отработки программы». Эту задачу легко выполнить, если дать команду выделить одну любую другую ячейку. Например, в нашей программе можно снять выделение блока командой:

Cells(X, Y).Select

которая переводит курсор выделения ячеек на ячейку в начале выделенной таблицы.

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

Dim Mass() As Variant

Dim obmen As Variant

Dim i As Integer

Dim j As Integer

Dim X As Integer

Dim Y As Integer

Dim H As Integer

Dim W As Integer

Dim K As Integer

Dim L As Integer

Dim M As Integer

"Получить характеристики выделенной области

X = Selection.Row

Y = Selection.Column

H = Selection.Rows.Count

W = Selection.Columns.Count

"Заказать в памяти массив

ReDim Mass(H, W)

"Получить из выделенной зоны данные

obmen = Cells(X + i - 1, Y + j - 1)

If VarType(obmen) > 1 And VarType(obmen) < 6 Then

Mass(i, j) = obmen

MsgBox "В ячейке " + Chr(Y + i + 63) + LTrim(Str(X + i - 1)) + _

" НЕ числовые данные"

"Переставить данные в порядке возрастания

If Mass(i, j) > Mass(K, M) Then

obmen = Mass(i, j)

Mass(i, j) = Mass(K, M)

Mass(K, M) = obmen

"Вывести новый порядок данных на лист EXCEL

Cells(X + i - 1, Y + j - 1) = Mass(i, j)

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

Тестирование и отладка программы

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

Ошибки, которые может допустить программист, условно делятся на три группы:

  1. Синтаксические
  2. Времени выполнения (run-time errors)
  3. Алгоритмические

Синтаксические ошибки

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


Рис. 27.1.

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

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

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

Ошибки времени выполнения (run-time errors) тоже, как правило, легко устранимы. Они обычно проявляются уже при первых запусках программы, или во время тестирования . Если такую программу запустить из среды Lazarus, то она скомпилируется, но при попытке загрузки, или в момент совершения ошибки, приостановит свою работу, выведя на экран соответствующее сообщение. Например, такое:


Рис. 27.2.

В данном случае программа при загрузке должна была считать в память отсутствующий текстовый файл MyFile.txt . Поскольку программа вызвала ошибку, она не запустилась, но в среде Lazarus процесс отладки продолжается, о чем свидетельствует сообщение в скобках в заголовке главного меню , после названия проекта. Программисту в подобных случаях нужно сбросить отладчик командой меню "Запуск -> Сбросить отладчик ", после чего можно продолжить работу над проектом.

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

Если программу запустить из самой Windows , при возникновении этой ошибки появится такое же сообщение. При этом если нажать "OK ", программа даже может запуститься, но корректно работать все равно не будет.

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

begin MySL:= TStringList.Create; MySL.Add("Новая строка"); end;

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

begin MySL:= TStringList.Create; MySL.Add("Новая строка"); ...; //работа с объектом MySL.Free; //освободили объект end;

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

begin try MySL:= TStringList.Create; MySL.Add("Новая строка"); ...; //работа с объектом finally MySL.Free; //освободили объект, даже если была ошибка end; end;

Итак, во избежание ошибок времени выполнения программист должен не забывать делать проверку на правильность ввода пользователем допустимых значений, заключать опасный код в блоки try…finally…end или try…except…end , делать проверку на существование открываемого файла функцией FileExists и вообще соблюдать предусмотрительность во всех слабых местах программы. Не полагайтесь на пользователя, ведь недаром говорят, что если в программе можно допустить ошибку, пользователь эту возможность непременно найдет.

Алгоритмические ошибки

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

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

Если программа работает правильно с одними наборами исходных данных, и неправильно с другими, то это свидетельствует о наличии алгоритмической ошибки. Алгоритмические ошибки иногда называют логическими, обычно они связаны с неверной реализацией алгоритма программы: вместо "+" ошибочно поставили "-", вместо "/" - "*", вместо деления значения на 0,01 разделили на 0,001 и т.п. Такие ошибки обычно не обнаруживаются во время компиляции , программа нормально запускается, работает, а при анализе выводимого результата выясняется, что он неверный. При этом компилятор не укажет программисту на ошибку - чтобы найти и устранить её, приходится анализировать код, пошагово "прокручивать" его выполнение, следя за результатом. Такой процесс называется отладкой .

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

Цель лекции: ознакомиться с видами и способами контроля и тестирования ПО, методами и средствами отладки программ.

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

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

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

    следует избегать тестирования программы автором;

    необходимо досконально изучать результаты каждого теста;

    необходимо проверять действия программы на неверных данных;

    необходимо проверять программу на неожиданные побочные эффекты на неверных данных.

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

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

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

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

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

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

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

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

    синтаксические ошибки – сопровождаются комментарием с указанием их мес­тоположения, фиксируются компилятором (транслятором) при выполнении синтаксического и частично се­мантического анализа;

    ошибки компоновки - обнаруживаются компоновщиком (редакто­ром связей) при объединении модулей программы;

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

    ошибки определения исходных данных (ошибки передачи, ошибки преобразования, ошибки перезаписи и ошиб­ки данных);

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

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

Отладка программы в любом случае предполагает обдумывание и логи­ческое осмысление всей имеющейся информации об ошибке. Большинство ошибок можно обнаружить по косвенным признакам посредством тщатель­ного анализа текстов программ и результатов тестирования без получения дополнительной информации с помощью следующих методов:

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

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

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

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

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

Общая методика отладки программных продуктов, написанных для выполнения в операционных системах MS DOS и Win32:

1 этап - изучение проявления ошибки;

2 этап – определение локализации ошибки;

3 этап - определение причины ошибки;

4 этап - исправление ошибки;

5 этап - повторное тестирование.

Процесс отладки можно существенно упрос­тить, если следовать основным рекомендациям структурного подхода к про­граммированию:

    программу наращивать «сверху-вниз», от интерфейса к обрабатываю­щим подпрограммам, тестируя ее по ходу добавления подпрограмм;

    выводить пользователю вводимые им данные для контроля и прове­рять их на допустимость сразу после ввода;

    предусматривать вывод основных данных во всех узловых точках ал­горитма (ветвлениях, вызовах подпрограмм).

Дополнительную информацию по теме можно получить в .

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

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

  1. Синтаксическая ошибка . Неправильное употребление синтаксических конструкций, например употребление оператора цикла For без то или Next.
  2. Семантическая ошибка . Нарушение семантики той или иной конструкции, например передача функции параметров, не соответствующих ее аргументам.
  3. Логическая ошибка . Нарушение логики программы, приводящее к неверному результату. Это наиболее трудный для "отлова" тип ошибки, ибо подобного рода ошибки, как правило, кроются в алгоритмах и требуют тщательного анализа и всестороннего тестирования.

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

В каждой современной системе программирования существует специальное средство отладки программ - отладчик (debugger), который позволяет в режиме интерпретации установить контрольные точки, выполнить отдельные участки программы и посмотреть результаты работы операторов. Естественно, что редактор Visual Basic имеет подобное средство, с которым мы сейчас и познакомимся. В вышеописанной программе мы специально допустили ошибки, на примере которых и продемонстрируем работу отладчика VBA.

Замечание

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

Первый шаг отладки - это запуск компилятора: Debug > compile <имяПроекта>. Компилятор, просматривая код программы, найдет ошибку и выдаст сообщение: sub or Function not defined (Процедура или функция не определены), выделив место ошибки (creatitem) в теле процедуры.

Итак, допущена синтаксическая ошибка, мы сделали опечатку (вместо createitem ввели creatitem), и компилятор стал расценивать это как вызов процедуры пользователя, которая нигде не объявлена. Быстро исправим эту оплошность, добавив злополучную е в код:

Set tsk = Createltem(olTaskltem)

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

Замечание

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

Запуск программы в VBA осуществляется разными способами. Уже упоминалась возможность запуска программы посредством нажатия клавиши или с помощью команды Run Sub\UserForm меню Run. Однако при таком вызове запускается активная процедура, т. е. процедура, в которой находится курсор. Другим Способом является вызов диалогового окна Macros из меню Tools. В этом окне можно выбрать запускаемую процедуру, не делая ее активной.

Итак, мы запустили программу. Что же происходит? Сразу после запуска появляется диалоговое ОКНО об ошибке: Object variable or With block variable not set (объектная переменная или переменная блока with не определена) и четыре варианта продолжения работы с программой (рис. 22.6):

  1. Continue. Продолжить выполнение программы.
  2. End. Закончить выполнение программы.
  3. Debug. Прервать выполнение программы и перейти в режим отладки.
  4. Help. Вывести подробную справку об ошибке.

Замечание

Хотя в данном случае кнопка Continue не активна, она бывает очень полезна в ряде случаев. Например, при прерывании хода программы комбинацией клавиш + только для проверки контрольных значений в окне Immediate, когда нет необходимости переходить в режим отладки, если все значения удовлетворительны. Кнопка End используется для окончательного прерывания хода программы, как правило, когда ошибка сразу видна и не требует отладочных средств.

Рис. 22.6. Диалоговое окно Run-time error "91"

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

В нашем же случае произошла семантическая ошибка: неправильное присваивание переменной значения ссылки на объект. Для устранения этой ошибки необходимо добавить оператор присваивания set перед переменной tsk. Давайте еще раз запустим программу. На этот раз она успешно завершилась, дойдя до конца и выдав сообщение "Задача успешно поручена".

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

Как видите, все параметры верны, кроме загадочного срока окончания задачи, который истекает через 5 дней, в то время как в диалоговом окне продолжительность проекта была равна 5 месяцам!!!

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

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

Рис. 22.7.

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

Чтобы создать точку останова, следует в отлаживаемой процедуре установить точку ввода в любом месте строки кода VBA, перед выполнением которой вы хотите остановить выполнение процедуры. Затем нужно выбрать команду > Debug > Toggle Breakpoint или просто нажать клавишу . При этом строка будет выделена коричневым цветом, а на левом поле окна кода появится жирная коричневая точка. Для снятия точки останова нужно еще раз повторить те же действия. Если напротив оператора стоит точка ос танова, это означает, что выполнение программы будет приостановлено перед выполнением этого оператора.

Замечание

Есть и более простой и, на наш взгляд, естественный способ установки точек останова: достаточно просто сделать щелчок мышью по серой полоске у левого края соответствующей строки кода. Снять эту точку можно повторным щелчком по жирной коричневой точке. Наконец, если вы хотите снять все ранее поставленные точки останова, вовсе необязательно снимать все эти точки поодиночке. Достаточно воспользоваться командой меню > Debug > Clear All Breakpoints.

Наши подозрения вызвали следующие места программы, в которых мы и расставили точки останова (рис. 22.8).

  • Инициализация переменной tsk (чему равняется значение по умолчанию).
  • Вызов стандартной функции NOW (действительно ли возвращается текущее время).
  • Установка даты окончания задачи (правильно ли происходит суммирование).

После расстановки точек останова необходимо, как было сказано, указать, значения каких переменных мы хотели бы наблюдать. Естественно, что мы выбрали значения полей tsk.startoate и tsk.DueDate. Для наблюдения за несколькими свойствами или переменными существуют специальные окна Locals Window и Watch Window. Эти окна можно открыть с помощью соответствующих кнопок на панели Debug или команд меню View.

В окне локальных переменных можно наблюдать за значением всех локальных переменных выполняемой в данный момент процедуры, а окно контрольных значений предназначено для постоянного наблюдения за выбранными пользователем переменными или свойствами. Чтобы определить контрольное значение, достаточно выделить в окне модуля любую переменную, выражение или свойство и нажать кнопку Quick Watch на панели инструментов Debug. При этом появится диалоговое окно, в котором указано имя подпрограммы, само выражение, а также его текущее значение (рис. 22.8).

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

Рис. 22.8. Точки останова и диалоговое окно Quick Watch

Пример 22.8. Добавление переменной в окно Add Watch

{В окне Watch}

1R Add Watch... (рис. 22.9)

Expression:= tsk.StartDate

Procedure AssignTask

Итак, точки останова расставлены, окно Add Watch с наблюдаемыми переменными активно, следовательно, с замиранием сердца переходим к трассировке программы. Итак, нажимаем клавишу , как и предполагалось, перед инициализацией переменной происходит останов программы. Все правильно. Теперь давайте посмотрим, как изменились значения переменных В окне Add Watch: tsk.StartDate = 01:01:4501, tsk.StartDate = 01:01:4501, a duration = 5.

Рис. 22.9. Диалоговое окно Add Watch

Для единичного просмотра значения переменной можно просто подвести к ней указатель мыши, и вы увидите всплывающую подсказку. Например, duration = 5.

Для дальнейшего пошагового выполнения программы можно воспользоваться одним из трех способов:

  1. Step Into. При нажатии клавиши выполняется очередной оператор, после чего выполнение программы приостанавливается и программа становится доступна для корректировки.
  2. Step Over. Нажатие комбинации клавиш + осуществляет вызов вспомогательных процедур и функций за один шаг, что дает возможность не задерживаться на их выполнении.
  3. Step Out. Данная комбинация клавиш ++ позволяет выйти из выполняемой вспомогательной процедуры, не дожидаясь конца ее пошагового выполнения.

Итак, нам необходимо нажать клавишу и посмотреть, чему стало равно значение tsk.startDate. Как и следовало ожидать, переменной было присвоено значение 21.08.01. (текущая дата 21 августа 2001 года). Следовательно, функция Now работает корректно.

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

DueDate = DateAdd("m", duration, .StartDate)

Замечание

Встроенная функция DateAdd предназначена для добавления или вычитания из даты указанного числа временных интервалов.

В конце рассказа об отладчике мы решили на рис. 22.10 показать панель инструментов Отладка (Debug) с кнопками, используемыми при отладке, а в табл. 22.1 привести краткую справку по всем использованным и неиспользованным средствам отладчика.

Рис. 22.10. Кнопки панели Отладка

Команда Назначение
Compile Компиляция программы
Run Sub/UserForm Запуск процедуры или формы
Break Прерывание выполнения программы +
Reset Остановка выполнения программы
Toggle Breakpoints Установить точку останова
Clear All Breakpoints Снять все точки останова
Step Into Шаг с заходом во вспомогательные процедуры
Step Over Шаг с обходом вспомогательных процедур
Step Out Шаг с выходом из вспомогательной процедуры
Step to Cursor Шаг до курсора. Запускает программу на выполнение до строки с курсором
Set Next Statement Позволяет устанавливать следующий выполняемый оператор
Show Next Statement Показывает следующий выполняемый оператор
Immediate Window Отображает окно отладочных результатов вычисления
Locals Window Отображает окно локальных переменных процедуры
Watch Window Отображает окно контрольных выражений программы
Add Watch Добавляет выражение в окно Watch
Edit Watch Исправляет выражение в окне Watch
Quick Watch Просматривает значение выделенного выражения
Call Stack Позволяет показать стек вызовов процедур в текущий момент. Эта кнопка очень полезна при работе с рекурсивными процедурами
Comment Block Позволяет закомментировать выделенный блок операторов
Uncomment Block Отменяет сделанные комментарии
Toggle Bookmarks Устанавливает закладку
Clear All Bookmarks Снимает все установленные закладки
Find Вызывает диалоговое" окно поиска, посредством которого можно найти ту или иную переменную, выражение и т. д.

Таблица 22.1. Средства отладчика

К сожалению, не все приемы отладки можно рассмотреть на нашем простейшем примере.