Выбрать главу

Assertions (С). Эта опция более полно описана в следующем разделе. Использование данного типа проверок позволяет быстро и просто добавить проверки в код Естественно, в коммерческой версии вы захотите отключить эту возможность. Директивы компилятора— $С+ и $С-.

Overflow checking (Q). Проверка на переполнение позволяет выяснить, не является ли результат выполнения целочисленной операции слишком большим для размещения его в переменной. Подобно опции Range Checking, данная опция полезна только при отладке, и в коммерческой версии, как правило, отключается. Директивы компилятора— $Q+ и $Q-. Отладочная версия вашего кода, вероятно, будет больше по размеру и медленнее коммерческой версии. Поэтому не передайте случайно конечному пользователю отладочную версию!

Использование директивы Assert

Оператор Assert— новый оператор в Delphi 4. В действительности это просто тест на логическую истину/ложь. При использовании этого оператора вы убеждаетесь, что логическое выражение истинно, если при выполнении выражение становится ложным, генерируется исключительная ситуация. Синтаксис использования оператора таков:

Assert (<логическое выражение)

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

procedure Foo(Count: Cardinal);

begin

Assert(Count < SizeOf(Word));

end;

Если выражение окажется ложным, появится сообщение об ошибке, подобное показанному на рис. 2.3. Конечно же, у вас уже вертится на языке вопрос, чем же это отличается от конструкции if… else. Дело в том, что управлять генерацией кода для оператора Assert очень легко и просто с помощью директивы компилятора. Для применения описанных возможностей используйте директиву $ASSERTIONS ON или $С +, а для отключения действия Assert— $ASSERTIONS OFF или $С — (при этом компилятор игнорирует операторы Assert и код для них не генерируется).

Рис. 2.3.Сообщение об ошибке Assert

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

{$ifdef Debug}

($ASSERTIONS ON)

{$else}

($ASSERTIONS OFF)

{$endif}

Какого типа выражения могут использоваться в операторе Assert? Любого (конечно, если оно возвращает логическое значение). Однако тут есть свои маленькие подводные камушки, о которые легко поцарапаться. Представьте себе, что у вас есть некоторая функция, например выясняющая, сколько раз она была вызвана.

function CountMe: Integer;

const ReferenceCount: Integer = 0;

begin

Inc(ReferenceCount);

Result:= ReferenceCount;

end;

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

Модульное тестирование

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

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

Рис. 2.4.О чем думают пользователи, когда ваша программа выводит сообщение об ошибке?..

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