Файл: Освой самостоятельно программирование для MS Access 2002 за 24 часа [П.Киммел].pdf

ВУЗ: Не указан

Категория: Не указан

Дисциплина: Не указана

Добавлен: 21.10.2020

Просмотров: 7954

Скачиваний: 25

ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
background image

• Код компилируется и запускается без ошибок — скажем, нет сообщений о

том, что некий объект отсутствует.

• Задача решается верно.
• Код способен обработать самые серьезные ошибки времени выполнения.

Если программа, пройдя через все испытания, "выжила", вы должны решить, что де-

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

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

стороны", чтобы еще раз удостовериться, все ли ситуации предусмотрены и протестиро-

ваны. В противном случае вам придется зафиксировать сделанное документально и пе-

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

также в том случае, если в вашем коллективе есть специальная группа, занимающаяся

тестированием и проверкой качества выпускаемого программного обеспечения.

Если код "споткнулся" на каком-либо из трех названных этапов, вам пригодится

информация, изложенная в следующих разделах.

Как избавиться от необоснованных взаимозависимостей

блоков кода

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

функции или неудовлетворительной реализации зависимости от какого-либо другого

внешнего объекта кроются в особенностях стиля вашей работы.

Если код ссылается на внешний объект или переменную, которые в данный мо-

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

тестируемой функции или класса — другими словами, передавайте его имя в виде па-

раметра процедуры или функции либо включите в набор свойств класса. (Подробнее о

классах и их атрибутах см. главу "21-й час. Основы программирования

Общее правило таково: не прекращайте работу над кодом, содержащим необоснован-

ные внешние ссылки и зависимости.

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

набора аргументов процедуры/функции. Тщательно проанализируйте, какие глобаль-

ные переменные имеет смысл преобразовать в локальные. Глобальные объекты — по-

тенциальный источник ошибок и недоразумений.

Если тестируемый блок кода ссылается на процедуру или функцию, подумайте,

действительно ли она необходима.

Что делать, если код работает неверно

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

неверные исходные данные, попробуйте сформулировать условия, которым должны

удовлетворять данные, и дополните код условными конструкциями, которые смогут га-

рантировать корректность обрабатываемой информации. Более подробные сведения по

этим вопросам приведены ниже, в разделе "Верификация исходных условий".

Если код неверен сам по себе — что ж, разбирайтесь и исправляйте ошибку. Мож-

но сказать одно — найти и устранить дефект гораздо легче в небольшом фрагменте

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

Как быть в случае возникновения непредусмотренной

ситуации

ЕСЛИ во время выполнения кода возникает непредвиденная ошибка, первым делом

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

мого блока от других объектов программы. В этом случае выполните рекомендации,

300 Часть VI. Работа над ошибками


background image

рассмотренные выше. Часто ошибку можно устранить с помощью программного об-

работчика. Иногда достаточно просто зафиксировать ее, а затем попытаться "обойти".

Возможность установить закономерность возникновения ошибки — это уже нема-

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

но "вывесить" на экран окно с подробным объяснением случившегося. Представьте

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

нет, программа работать не будет. Сообщите об этом пользователю и предложите спо-

собы выхода из создавшейся ситуации.

В тестовых процедурах могут применяться специальные конструкции и приемы,

позволяющие выявить потенциальные ошибки. Об этом будет рассказано далее.

Использование ловушек

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

давно. Заслуга принадлежит Дэйву

 (Dave Thielen). Достаточно сказать, что

этот человек отвечал за разработку MS DOS 5. Если в то время вы уже занимались

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

версия операционной системы DOS. Она просто пестрила ошибками. Всемогущий

Билл Гейтс, возможно, сказал тогда: "Друзья мои! Либо в пятой версии вы исправите

недочеты, либо всех уволю без выходного пособия".

Так вот, DOS 5 завоевала успех и признание миллионов пользователей. Позже

Дэйв

 написал книгу

 No

 Delivering

 Code in С and C++

(издательство

 1992). Это пособие — одно из моих любимых, и тому

есть две причины. Первая — небольшой объем, всего около 180 страниц (сравните со

многими современными фолиантами, для которых 1000 страниц становится порочной

нормой). А вторая — пожалуй, главная — заключается в том, что в книге излагаются

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

свет и по сей день я с успехом применяю в процессе программирования на любом

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

рования сочли необходимым включить некоторые предложенные Дэйвом Тиленом

технологии в состав своих продуктов. Скажем, VBA содержит штатные средства вери-

фикации условий.

Под

 верификатором условий

 понимается дополнительный код, который осуществ-

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

программы, если последние не удовлетворяются. В процессе

 трассировки

 программа с

помощью вспомогательных конструкций создает отчет — во внешнем файле или в ок-

не (в таком, например, как Watches) — о том, что она делает. Скажем, Microsoft Visual

C++ предлагает инструменты верификации условий и трассировки, а язык Object Pas-

cal среды Delphi имеет собственные возможности верификации. Языки VB и VBA

также снабжены средствами верификации условий и аналогом трассировки — функ-

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

Что такое ловушка

Слово

 ловушка

 (trap) достаточно понятно: вы попадаете в нее, и она захлопывается.

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

вериться в том, что некий блок выполнился. Ее цель — уведомить, что в процессе

своего выполнения программа "прошла" через определенное место кода.

Использование ловушек — удобное средство, гарантирующее, что процессом

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

тестировании управляющей структуры If

 Then

 Else

 End

 блок

 час. Отладка кода 301


background image

кода, следующий за Else, никогда не выполнялся. Вправе ли вы надеяться, что в
один не очень прекрасный момент он вас не подведет? Ответ однозначен — нет.

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

Как

 ловушки

В VBA технология применения ловушек реализуется очень легко. Изучите текст

листинга

Листинг

 Пример использования ловушек

1 Sub

 FileName

 As

 String,

 As Long)

2

 "Ловушка:

 & FileName &

 & TrapNumber &

3 Stop
4 End Sub

5
6 Sub

 )

7 Dim Condition As Boolean

8 If (Condition = True) Then
9 Call

 1 )

10: Else
11: Call Trap( "Modulel", 2 )

 End If

 Sub

Строки

 содержат текст процедуры-ловушки, а строки

 заня-

I ты процедурой, подвергаемой тестированию. Процедура Trap доста-

точно проста. Ее можно создать один раз, а затем при необходимости

импортировать в нужные модули. В нашем случае Trap вызывается с
двумя аргументами — именем модуля (FileName) и номером строки-
ловушки (TrapNumber), который должен быть уникальным в пределах
текущего модуля.

Когда ловушка "захлопывается", вызывается процедура Trap, которая выводит

информацию об имени модуля и номере блока кода в окно отладки. Во время выпол-

нения программы следите за содержимым окна Immediate и помечайте все пройден-

ные строки-ловушки символом комментария. Не советуем полностью удалять эти

строки из текста программы — их наличие в виде комментариев говорит о том, что

соответствующие блоки кода были протестированы.

Строки 6—  представляют собой пример кода, который должен пройти тестиро-

вание с помощью ловушек. Применяйте строки-ловушки в особо ответственных

случаях — скажем, в важных условных конструкциях. Конечно, весь код проверять

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

тестирования, разумеется, не следует. Если ранее проверенный код подвергся изме-

нениям, желательно убрать символ комментария и повторить тест вновь. Если при

просмотре текста программы вы нашли строку-ловушку, не помеченную символом

комментария, сразу же протестируйте эту часть кода. Если не удается подобрать со-

ответствующие условия теста, подумайте — может быть, такой блок кода вовсе и не

нужен. Его удаление обеспечит полную гарантию избавления от потенциальных не-

приятностей (кто из классиков мрачно пошутил: "Наилучшее средство от головной

боли —

302

Часть VI. Работа над ошибками


background image

Трассировка кода

Значение глагола

 trace

 (следить), от которого происходит название необходимого в ра-

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

 или подглядывать в замочную скважину вам не придется.) Назначение функций

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

полезной в процессе выявления блоков кода,

 в оптимизации.

Приемы реализации процедур трассировки схожи с методами использования лову-

шек, рассмотренными в предыдущем разделе. Процедуре трассировки передается не-
сколько аргументов — имя тестируемого модуля (скажем,

 номер блока кода,

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

 По значению аргумента Tra-

ceNumber блок кода легко отыскать в тексте модуля с помощью команды меню

 окна редактора VBA. В качестве параметра TraceMessage можно передавать

имя выполняемой в данный момент процедуры или функции, значение переменной или

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

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

Только на протяжении последних пяти лет в составе инструментальных
сред программирования появились мощные интегрированные отлад-
чики, позволяющие указывать объекты наблюдения (watches), следить
за содержимым стека вызовов (call stack) и задавать точки останова

(breakpoints). Средства наблюдения и просмотра стека вызовов можно,
по существу, приравнять к функциям трассировки, а механизмы обра-
ботки точек останова близки по смыслу процедурам использования

ловушек и верификации условий.

Впрочем, одно вовсе не исключает другого — рассматриваемые

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

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

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

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

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

информацию в виде файлового отчета, а не только отображать ее в окне Immediate редак-
тора

 Сопоставление полученного отчета с тем, что, по вашему мнению, должна была

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

Листинг 17.2. Пример процедуры трассировки

1: Sub

 FileName As String,

2: ByVal TraceMessage As String, ByVal TraceNumber As Long)

 Dim Output As String

4: Output =

 & FileName &

 &

 TraceNumber &

 в

 & Now & vbCrLf &

17-й час. Отладка кода

303


background image

6:

 &

 Output

 End Sub

[ Листинг

 содержит текст процедуры трассировки. Добавьте ее в тот

I же модуль, который собираетесь проверять, и вы получите удобное сред-

ство тестирования. Если необходимо применить готовую процедуру трас-

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

 File) и импорта

 File) модуля.

В строке 3 объявляется переменная для хранения строки данных, форматируемой ниже

(в строках

 в соответствии с шаблоном

 в

 Пре-

допределенная константа vbCrLf содержит управляющие символы возврата каретки и пе-

ревода строки, позволяющие разбить одну логическую строку данных на несколько физи-

ческих, которые с помощью команды Debug.Print отображаются затем в окне Immediate.

Другая версия процедуры Trace могла бы осуществлять вывод информации в жур-

нальный текстовый файл. (Я, например, в свое время использовал обе.) Чтобы реали-

зовать подобный код, необходимо открыть (Open) текстовый файл в режиме Append,
использовать команду Write для записи в него форматированной строки, а затем за-

крыть (Close) файл.

Собираясь "поохотиться за ошибками", держите эти орудия под рукой — во время

отладки своих драгоценных программ вы сэкономите массу времени и нервов.

Верификация исходных условий

Без начальных условий и предположений программирование вообще невозможно.

Используя конструкции верификаторов, вы требуете выполнения оговоренного усло-

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

ны, что соответствующие методы были включены в состав классов большинства со-

временных систем программирования.

Класс Debug в

 содержит метод Assert. Функция Assert предполагает задание

единственного параметра типа

 (проверяемого условия) и приостанавливает вы-

полнение программы, если условие не выполнено. Собственно, это как раз то, что нуж-

но. Assert играет роль "блюстителя порядка". Если для корректной работы программы

необходимо выполнить определенное условие, Assert аккуратно за этим проследит.

Существует, вероятно, столько же примеров использования верификаторов, сколько

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

вы намереваетесь обновить содержимое файла, то файл (это совершенно очевидно) дол-

жен существовать. Конечно, можно было бы написать, скажем, такую строку кода:

If

 Dir( FileName ) ) > 0) Then

Во время выполнения программы подобная конструкция, безусловно, в состоянии

проверить факт существования файла, но она не сможет довести до сведения про-

граммиста (и пользователя) информацию о том, что файла не существует. Но если код

несколько расширить (как показано ниже), он от этого только выиграет, увеличив

свою функциональность:

 FileName } ) > 0

If (Len(

 FileName ) ) > 0) Then

Если условие верификации не удовлетворяется, программа приостанавливает вы-

полнение на текущей строке кода. Причины ошибки могут быть различными — файл

оказался удаленным другим процессом, аргументу FileName передано неверное зна-

чение и т.п. В любом случае верификатор даст знать, что оговоренное вами обяза-

тельное условие не выполнено.

304 Часть VI. Работа над ошибками