Добавил:
Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Роббинс Д. - Отладка приложений для Microsoft .NET и Microsoft Windows - 2004

.pdf
Скачиваний:
321
Добавлен:
13.08.2013
Размер:
3.3 Mб
Скачать

ГЛАВА 3 Отладка при кодировании

131

 

 

Перед тем как ринуться в разбор особенностей для разных платформ, хочу упомянуть об одном исключительном инструменте, который всегда должен быть на машинах для разработки: DebugView. Мой бывший сосед Марк Руссинович (Mark Russinovich) написал DebugView и массу других потрясающих инструментов, ко торые можно скачать с сайта Sysinternals (www.sysinternals.com). У них отличная цена (бесплатно!), многие инструменты доступны с исходным кодом и решают некоторые очень сложные проблемы, а потому вам стоит посещать Sysinternals хоть раз в месяц. DebugView отслеживает все вызовы к OutputDebugString пользователь ского режима или к DbgPrint режима ядра, так что вы сможете видеть всю отла дочную информацию, не работая в отладчике. Что делает DebugView еще более полезным, так это его способность работать с другими машинами, и вы сможете следить за всеми машинами распределенной системы с одного компьютера.

Трассировка в Windows Forms и консольных приложениях .NET

Как я сказал, Microsoft наделала маркетингового шума вокруг трассировки в при ложениях .NET. В общем, они неплохо потрудились при создании хорошей архи тектуры, которая лучше управляет трассировкой в реальных разработках. Говоря об утверждениях, я уже упоминал объект Trace, поскольку он необходим для трас сировки. Как и Debug, для обработки вывода объект Trace использует концепцию применения TraceListener. Поэтому мой код утверждений в ASP.NET менял прием ники для обоих объектов: так весь вывод направляется в одно место. В коде ут верждений из ваших разработок вам лучше поступать так же. Вызовы методов объекта Trace активны, только если определен параметр TRACE. По умолчанию он определен в проектах и отладочных, и финальных сборок, создаваемых Visual Studio

.NET, поэтому скорее всего методы уже активны.

Объект Trace содержит четыре метода для вывода информации трассировки: Write, WriteIf, WriteLine и WriteLineIf. Вероятно, вы догадались о разнице между Write и WriteLine, но понять методы *If сложнее: они позволяют осуществлять услов ную трассировку. Если первый параметр метода *If принимает значение true, вы полняется трассировка, false — нет. Это довольно удобно, но при неосторожном обращении может привести к серьезным проблемам с производительностью. Так, написав код, вроде показанного в первой части следующего отрывка, вы будете испытывать издержки от конкатенации строк при каждом выполнении этой строки кода, так как необходимость трассировки определяется внутри вызова Trace. WriteLineIf. Гораздо лучше следовать второму примеру из фрагмента, где опера тор if для вызова Trace.WriteLine используется только при необходимости, мини мизируя издержки от конкатенации строк.

// Испытываем издержки каждый раз.

Trace.WriteLineIf ( bShowTrace , "Parameters: x=" + x + " y =" + y ) ;

// Выполняем конкатенацию, только когда это необходимо. if ( true == bShowTrace )

{

Trace.WriteLine ("Parameters: x=" + x + " y =" + y ) ;

}

132 ЧАСТЬ I Сущность отладки

Думаю, разработчики .NET оказали нам всем большую услугу, добавив класс TraceSwitch. При наличии методов *If в объекте Trace, позволяющих выполнять трассировку по условию, остается лишь шаг до определения класса, предоставля ющего несколько уровней трассировки и единый способ их установки. Важней шая часть TraceSwitch — это имя, присваиваемое ему в первом параметре конст руктора. (Второй параметр — это описательное имя.) Имя позволяет управлять объектом снаружи приложения, о чем я расскажу через секунду. В объектах Trace Switch заключены уровни трассировки (табл. 3 3). Для проверки соответствия TraceSwitch определенному уровню служит набор свойств, таких как TraceError, возвращающих true, если объект соответствует данному уровню. В сочетании с методами *If использование объектов TraceSwitch вполне очевидно.

public static void Main ( )

{

TraceSwitch TheSwitch = new TraceSwitch ( "SwitchyTheSwitch", "Example Switch" );

TheSwitch.Level = TraceLevel.Info ;

Trace.WriteLineIf ( TheSwitch.TraceError ,

"Error tracing is on!" ) ; Trace.WriteLineIf ( TheSwitch.TraceWarning ,

"Warning tracing is on!" ) ; Trace.WriteLineIf ( TheSwitch.TraceInfo ,

"Info tracing is on!" ) ; Trace.WriteLineIf ( TheSwitch.TraceVerbose ,

"VerboseSwitching is on!" ) ;

}

Табл. 3-3. Уровни TraceSwitch

Уровень трассировки

Значение

Off — Выкл.

0

Error — Ошибки

1

Warnings (and errors) — Предупреждения (и ошибки)

2

Info (warnings and errors) — Информация (предупреждения и ошибки)

3

Verbose (everything) — Полная информация

4

 

 

Чудо объектов TraceSwitch в том, что ими легко управлять снаружи приложе ния из вездесущего файла CONFIG. В элементе switches, вложенном в элемент system.diagnostic, указываются элементы add, с помощью которых добавляются и устанавливаются имена и уровни. В листинге 3 7 показан полный конфигураци онный файл для приложения. В идеале для каждой сборки в приложении надо иметь отдельный объект TraceSwitch. Помните, что параметры TraceSwitch также можно применять к глобальному файлу MACHINE.CONFIG.

Листинг 3-7. Установка флагов TraceSwitch в конфигурационном файле

<?xml version="1.0" encoding="UTF 8" ?>

<configuration>

<system.diagnostics>

ГЛАВА 3 Отладка при кодировании

133

 

 

<switches>

<add name="Wintellect.ScheduleJob" value="4" />

<add name="Wintellect.DataAccess" value="0" />

</switches>

</system.diagnostics>

</configuration>

Трассировка в приложениях ASP.NET и Web-сервисах XML

Несмотря на наличие прекрасно продуманных объектов Trace и TraceSwitch, ASP.NET

и— как расширение — Web сервисы XML содержат совершенно иную систему трассировки. Исходя из размещения вывода трассировки ASP.NET, я могу понять причину этих различий, но все равно считаю, что они сбивают с толку. Класс System.Web.UI.Page содержит собственный объект Trace, наследуемый от System.Web.Tra ceContext. Чтобы не путать эти два разных варианта трассировки, я буду ссылать ся на вариант ASP.NET как на TraceContext.Trace. Два ключевых метода Trace Context.Trace — это Write и Warn. Оба они обрабатывают вывод трассировки, но Warn записывает вывод красным цветом. Каждый метод имеет три перегруженных вер сии, и оба принимают одинаковые параметры: обычное сообщение и категорию с вариантами сообщений, но есть версия, принимающая категорию, сообщение

иSystem.Exception. Эта последняя версия записывает строку исключения, а также источник и строку где было сгенерировано исключение. Чтобы избежать лишних издержек в обработке, когда трассировка отключена, проверяйте, имеет ли свой ство IsEnabled значение true.

Самый простой способ включить трассировку — задать атрибуту Trace дирек тивы @Page, располагающейся в начале ваших ASPX файлов, значение true.

<%@ Page Trace="true" %>

Волшебная маленькая директива включает тонны информации трассировки, ко торая появляется в нижней части страницы, что довольно удобно, но так ее ви дите и вы, и пользователи. Честно говоря, информации трассировки так много, что я очень хотел бы, чтобы она была поделена на несколько уровней. Иметь информацию о файлах cookie (Cookies), наборах заголовков (Headers Collections) и серверных переменных (Server Variables) приятно, но чаще всего она не нужна. Все разделы вполне очевидны, но я хочу выделить раздел Trace Information, так как здесь появляются все вызовы к TraceContext.Trace. Даже если вы не вызывали TraceContext.Trace.Warn/Write, вы все равно увидите информацию в разделе Trace Information, потому что ASP.NET сообщает о вызове нескольких своих методов. В этом разделе и появляется красный текст при вызове TraceContext.Trace.Warn.

Устанавливать атрибут Trace в начале каждой страницы приложения скучно, поэтому разработчики ASP.NET ввели в WEB.CONFIG раздел, позволяющий управ лять трассировкой. Этот раздел, вполне логично названный trace, показан ниже:

<?xml version="1.0" encoding="utf 8" ?>

<configuration>

<system.web>

134 ЧАСТЬ I Сущность отладки

<trace

enabled="false"

requestLimit="10"

pageOutput="false"

traceMode="SortByTime"

localOnly="true"

/>

</system.web>

</configuration>

Атрибут enabled управляет включением трассировки для данного приложения. Атрибут requestLimit указывает, сколько запросов трассировки кэшировать в па мяти для каждого приложения. (Через секунду мы обсудим, как просмотреть эти кэшированные запросы.) Элемент pageOutput сообщает ASP.NET, показывать ли вывод трассировки. Если pageOutput задано true, вывод появляется на странице, как если бы вы установили атрибут Trace в директиве Page. Вероятно, вам не захочется менять элемент traceMode поскольку так информация в разделе трассировки Trace Infor mation отсортирована по времени. Если вы хотите увидеть сортировку по катего риям, задайте traceMode значение SortByCategory. Последний атрибут — localOnly — сообщает ASP.NET, должен ли вывод быть видим только на локальной машине или он должен быть виден для всех клиентских приложений.

Чтобы увидеть кэшированные запросы трассировки, когда pageOutput задано false, добавьте к каталогу приложения HTTP обработчик trace.axd, который отобразит страницу, позволяющую выбрать сохраненную информацию трассировки, кото рую вы хотите увидеть. Скажем, если имя вашего каталога — http://www.wintel lect.com/schedules, то, чтобы увидеть сохраненную информацию трассировки, используйте путь http://www.wintellect.com/schedules/trace.axd. Достигнув преде ла requestLimit, ASP.NET прекращает записывать информацию трассировки. Запись можно перезапустить, просмотрев страницу trace.axd и щелкнув ссылку Clear Current Trace в верхней части страницы.

Как видите, если не соблюдать осторожность в трассировке, ее увидят конеч ные пользователи, а это всегда пугает, так как разработчики печально известны операторами трассировки, способными повредить карьере, если вывод попадет в плохие руки. К счастью, установив localOnly в true, вы сможете просматривать трассировку только на локальном сервере, даже при доступе к журналу трасси ровки через HTTP обработчик trace.axd. Чтобы просмотреть журналы трассиров ки вашего приложения, вам просто придется применить величайший программ ный продукт, известный человечеству, — Terminal Services, и вы получите доступ к серверу прямо из своего офиса, даже не вставая из за стола. Стоит также изме нить раздел customErrors файла WEB.CONFIG для использования страницы default Redirect, чтобы при попытке доступа к trace.axd с удаленной машины конечные пользователи не увидели ошибку ASP.NET «Server Error in ‘Имя_приложения’ Application». Кроме того, тех, кто пытается получить доступ к trace.axd, стоит заносить в жур нал, особенно потому, что неудавшаяся попытка доступа, вероятно, указывает на хакера.

Сейчас кто то из вас, возможно, думает об одной проблеме с трассировкой в ASP.NET: ASP.NET содержит TraceContext.Trace, отправляющий свой вывод в одно

ГЛАВА 3 Отладка при кодировании

135

 

 

место, а DefaultTraceListener для объекта System.Diagnostic.Trace отправляет свой вывод куда то еще. В обычном ASP.NET это огромная проблема, но если вы при меняете код утверждений из BugslayerUtil.NET, описанный выше, то ASPTraceListener также используется как единый TraceListener для объекта System.Diagnostic.Trace, так что я перенаправляю всю информацию трассировки в TraceContext.Trace, чтобы вся она появлялась в одном месте.

Трассировка в приложениях C++

Почти всю трассировку в таких приложениях выполняет макрос C++, обычно носящий имя TRACE и активный только в отладочных сборках. В конечном счете функция, вызываемая им, вызовет OutputDebugString из Windows API, так что ин формацию трассировки можно видеть в отладчике или в DebugView. Помните: вызов OutputDebugString приводит к переходу в режим ядра. Это не очень важно для от ладочных сборок, но может отрицательно сказаться на производительности фи нальных сборок, так что учтите все вызовы, которые могут остаться в финальных сборках. Вообще в поисках способов повысить производительность Windows в целом, команда Windows удалила массу трассировок, на которые мы все привык ли полагаться, таких как сообщение о конфликте загрузки DLL, появлявшееся при загрузке DLL, и это привело к очень хорошему росту производительности.

Если у вас нет макроса TRACE, можете использовать мой — из состава Bugs layerUtil.DLL. Всю работу выполняют функции DiagOutputA/W из DIAGASSERT.CPP. Преимущество моего кода в том, что вы можете вызвать SetDiagOutputFile, пере дав ему как параметр описатель файла, и записывать всю трассировку в файл.

В дополнение к макросу TRACE в главе 18 описывается мой инструмент FastTrace для серверных приложений C++. Последнее, что хочется делать в приложениях, интенсивно использующих многопоточность, — это принуждать все потоки бло кироваться на синхронизирующий объект при включении трассировки. Инстру мент FastTrace дает максимально возможную производительность трассировки без потерь важных потоков информации.

Комментировать, комментировать и еще раз комментировать

Однажды мой друг Франсуа Полин (François Poulin), который весь день занима ется сопровождением кода, написанного другими, пришел со значком, на кото ром было написано: «Кодируй так, как будто тот, кто сопровождает твой код, — буйнопомешанный, который знает, где ты живешь». Франсуа, несомненно, псих, но в его словах есть огромный смысл. Хотя вам может казаться, что ваш код явля ет собой образец ясности и совершенно очевиден, без подробных комментариев для сопровождающих разработчиков он так же плох, как сырой ассемблер. Иро ния в том, что сопровождающим разработчиком вашего кода легко можете стать вы сами! Незадолго до начала работы над вторым изданием этой книги я полу чил по электронной почте письмо из компании, в которой работал лет 10 назад, с просьбой обновить проект, который я для них писал. Взглянуть на код, кото рый я писал так давно, было потрясающе! Потрясало и то, насколько плохие я делал комментарии. Вводя каждую строку кода, вспоминайте значок Франсуа.

136 ЧАСТЬ I Сущность отладки

Наша задача двойственна: разработать решение для пользователя и сделать его пригодным к сопровождению в будущем. Единственный способ сделать код со провождаемым — комментировать его. Под словами «комментировать его» я под разумеваю не просто создание комментариев, повторяющих то, что делает код; я подразумеваю документирование ваших предположений, подходов к решению задачи и причин, по которым выбран именно такой подход. Также следует соот носить свои комментарии с кодом. Обычные кроткие программисты сопровож дения могут впасть в сомнамбулическое состояние, пытаясь обновить код, дела ющий не то, что он должен делать согласно комментариям.

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

Каждая функция или метод требуют одного двух предложений, проясняющих:

что делает подпрограмма;

какие в ней приняты допущения;

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

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

каждое из возможных возвращаемых значений;

каждое исключение, самостоятельно генерируемое функцией.

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

Любой интересный алгоритм заслуживает полного описания.

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

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

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

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

Если вам хочется сказать: «Я настоящий хакер» или «Это было действительно сложно», — то, вероятно, лучше не комментировать функцию, а переписать ее.

Корректное и полное документирование в коде отличает профессионала от того, кто просто играет в него. Дональд Кнут (Donald Knuth) как то заметил, что хоро шо написанная программа должна читаться как хорошо написанная книга. Хотя я не представляю себя захваченным сюжетом исходного кода TeX, я абсолютно согласен с мнением д ра Кнута.

Я рекомендую вам изучить главу 19 или сногсшибательную книгу Стива Мак Коннелла (Steve McConnell) «Совершенный Код» (Code Complete. — Microsoft Press, 1993). В этой главе рассказано как я учился писать комментарии. С правильными

ГЛАВА 3 Отладка при кодировании

137

 

 

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

Раз уж мы обсуждаем комментарии, хочу заметить, как сильно я люблю ком ментарии XML документации, введенные в C#, и как преступно то, что они не поддерживаются остальными языками от Microsoft. Надеюсь, в будущем все язы ки получат первоклассные комментарии XML документации. Имея ясный формат комментариев, который может быть извлечен при компоновке, вы можете начать создание целостной документации для вашего проекта. По правде говоря, я так люблю комментарии XML документации, что создал не очень сложный макрос CommenTater (см. главу 9), который добавляет и обновляет ваши комментарии XML документации и следит, чтобы вы не забывали добавлять их.

Доверяй, но проверяй (Блочное тестирование)

Я всегда считал, что Энди Гроув (Andy Grove) — бывший председатель совета ди ректоров Intel — был прав, назвав свою книгу «Выживают только одержимые» («Only the Paranoid Survive»). Это особенно верно для программистов. У меня много хо роших друзей — прекрасных программистов, но когда дело касается взаимодей ствия их кода с моим, я проверяю их данные до последнего бита. Вообще то у меня даже есть здоровый скепсис в отношении себя самого. С помощью утверждений, трассировки и комментариев я проверяю разработчиков своей команды, вызы вающих мой код. С помощью блочного тестирования я проверяю себя. Блочные тесты — это строительные леса, которые вы возводите, чтобы вызвать ваш код из за пределов программы как целого и убедиться, что код работает в соответствии с ожиданиями.

Первое, что я делаю для самопроверки, — начинаю писать блочные тесты од новременно с кодом, разрабатывая их параллельно. Определив интерфейс моду ля, я пишу для него функции заглушки (stub functions) и сразу создаю тестовую программу (или «обвязку» — harness) для вызова этих интерфейсов. Добавляя фрагменты функциональности, я добавляю новые варианты тестов в тестовую программу. С таким подходом я могу протестировать каждое следующее измене ние в отдельности и распределить создание тестовой программы по циклу раз работки. Если всю обычную работу вы делаете после реализации главного кода, то, как правило, у вас маловато времени для качественной работы над тестовой программой и реализации эффективного теста.

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

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

138 ЧАСТЬ I Сущность отладки

лать ваш код более расширяемым и пригодным для многократного использова ния. Поскольку многократное использование — это Святой Грааль программис тов, то все, что бы вы ни сделали для повышения используемости вашего кода, будет не напрасно. Хороший пример такой удачи — BugslayerStackTrace из Bugslayer Util.NET.DLL. Когда я впервые реализовывал код трассировки в ASP.NET, я встроил код для просмотра стека в класс ASPTraceListener. При тестировании я быстро понял, что информация о стеке может понадобиться мне и в других местах. Я извлек код просмотра стека из ASPTraceListener и поместил в отдельный класс — Bugslayer StackTrace. Когда мне потребовалось написать классы BugslayerTextWriterTraceListener

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

иполностью протестированный.

При кодировании следует выполнять блочные тесты постоянно. Кажется, я мыслю отдельными функциональными модулями примерно по 50 строчек кода. Каждый раз, добавляя или изменяя что либо, я перезапускаю блочный тест, что бы проверить, не нарушил ли я чего нибудь. Я не люблю сюрпризов и поэтому стараюсь свести их к минимуму. Настоятельно рекомендую вам выполнять блоч ные тесты перед внесением своего кода в главные исходные файлы. В некоторых компаниях существуют специальные тесты внесения (check in tests), которые должны выполняться до внесения кода. Я видел, как эти тесты внесения радикально снижали число неудавшихся компоновок и дымовых тестов.

Ключ к наиболее эффективному блочному тестированию заключается в двух словах: покрытие кода (code coverage). Если из этой главы вы не вынесете ниче го, кроме этих двух слов, я буду считать, что она удалась. Покрытие кода — это просто процент строк, запущенных в вашем модуле. Если в вашем модуле 100 строк

ивы запустили 85, то покрытие кода составляет 85%. Простая истина в том, что незапущенная строка — это строка, ждущая своей аварии.

Как консультанта, меня постоянно спрашивают, есть ли единый рецепт отлич ного кода. Сейчас я в том месте, откуда я впадаю в «религиозный экстаз», — на столько сильна моя вера в покрытие кода. Если бы вы сейчас стояли передо мной, то я бы прыгал вверх вниз, восхваляя достоинства покрытия кода с евангелист ским рвением. Многие разработчики говорили мне, что следование моему совету

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

Получить статистику покрытия кода можно двумя способами. Первый способ сложный и включает использование отладчика и установку точек прерывания в каждой строке вашего модуля. По мере выполнения строк удаляйте точки преры вания. Продолжайте выполнять код, пока не удалите все точки прерывания, и вы получите стопроцентное покрытие. Легкий путь заключается в применении ин струмента для покрытия от сторонних производителей, такого как TrueCoverage от Compuware NuMega, Visual PureCoverage от Rational или C Cover от Bullseye. Лично я не вношу код в главные исходные файлы, пока не запущу минимум 85–90% строк моего кода. Знаю, некоторые из вас сейчас застонали. Да, получение хорошего покрытия кода может занять много времени. Иногда приходится выполнять го раздо больше тестов, чем вы когда либо думали, и это может требовать времени. Получение хорошего покрытия подразумевает запуск вашего приложения в от ладчике и изменение переменных с данными для запуска участков кода, до кото

ГЛАВА 3 Отладка при кодировании

139

 

 

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

Нет ничего хуже бездействующего QA персонала, застрявшего на аварийных сборках. Если в ходе блочного тестирования вы получите 90% ое покрытие кода, ваши люди из отдела анализа качества могут использовать свое время для тести рования приложения на разных платформах и проверки работоспособности ин терфейсов между подсистемами. Работа QA отдела в том, чтобы тестировать про дукт как единое целое и сосредоточиться на качестве в целом, а ваша — в том, чтобы протестировать модуль и сосредоточиться на качестве этого модуля. Ког да обе стороны делают свою работу, результатом становится высококачественный продукт.

Ладно, я не жду, что разработчики будут проводить тесты на всех ОС Microsoft семейства Win32, которые могут применяться пользователями. Однако, если они смогут получить 90% ое покрытие хотя бы для одной ОС, команда выиграет две трети борьбы за качество. Если вы не используете один из инструментов покры тия от сторонних производителей, вы обманываете себя с качеством.

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

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

140 ЧАСТЬ I Сущность отладки

Резюме

В этой главе были представлены лучшие технологии профилактического програм мирования, используемые для отладки при кодировании. Лучшая методика заклю чается в повсеместном применении утверждений, чтобы получить контроль над ошибочными ситуациями. Представленные коды утверждений .NET в Bugslayer Util.NET.DLL и код SUPERASSERT устраняют все проблемы с утверждениями, предо ставляемыми компиляторами Microsoft. В дополнение к утверждениям правиль ная трассировка и комментарии могут облегчить вам и другим людям сопровож дение и отладку кода. Наконец, самый важный критерий оценки качества для про граммистов — блочное тестирование. Если вы сможете правильно протестиро вать свой код перед внесением его в главные исходные файлы, то избежите мас сы ошибок и проблем для обслуживающих инженеров в будущем.

Единственный способ правильно протестировать модуль — запустить при выполнении тестов инструмент для учета покрытия кода. До внесения кода в глав ные исходные файлы надо стараться получить покрытие минимум в 85–90%. Чем больше времени вы потратите на отладку при разработке, тем меньше его потре буется для отладки позднее.

Соседние файлы в предмете Программирование на C++