Главная - Литература

0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 [176] 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294

Определение источника ошибки

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

В нашем примере причиной проблемы может быть занижение или завышение на 1 при добавлении одной новой записи, но не двух или более. Однако изучение кода не приводит к нахождению очевидной ошибки занижения или завышения на 1. Тогда вы обращаетесь к плану Б и добавляете в БД одну новую запись, чтобы увидеть, вызовет ли это проблему. Вы добавляете запись Hardcase, Henry и предполагаете, что она займет неправильное место. При запуске программы выводится:

Formatting, Fred Freeform $5,877 Fruit-Loop, Frita $5,771

Global, Gary $1,666

Hardcase, Henry $493

Many-Loop, Mavis $8,889

Modula, Mildred $10,788

Statement, Sue Switch $4,000

Whileloop, Wendy $7,860

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

При более внимательном изучении выходных данных теста можно заметить, что только записи Fruit-Loop, Frita и Many-Loop, Mavis включают дефисы. Сразу же после ввода запись Fruit-Loop занимала неверное положение, но с записью Many-Loop все было в порядке, ведь так? Хотя распечатки результатов самого первого запуска программы у вас нет, вы помните, что вас смутило место записи Modula, Mildred, но она располагалась по соседству с Many-Loop. Возможно, ошибочным было положение записи Many-Loop, а не Modula.

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

Но как это объясняет тот факт, что проблема возникает только при вводе записи? Вы изучаете код и замечаете, что в программе используются два разных метода сортировки: один вызывается при вводе записи, а второй - при ее сохранении. Более тщательный анализ первого метода показывает, что он и не должен сортировать список полностью. Вставляя новую запись, он лишь приблизительно определяет ее положение для ускорения сортировки, которую выполняет второй метод. Так что проблема в том, что данные печатаются до их сортировки. Фамилии, содержащие дефисы, располагаются в неправильном порядке из-за того, что метод примерной сортировки не обрабатывает подобные тонкости. Теперь вы можете выдвинуть еще более точную гипотезу: фамилии, содержащие знаки пунктуации, правильно сортируются только во время сохранения.



Далее вы подтверждаете эту гипотезу при помощи дополнительных тестов.

Советы по поиску причин дефектов

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

Формулируя гипотезу, используйте все имеющиеся данные Выдвигая гипотезу об источнике дефекта, постарайтесь учесть как можно больше данных. В нашем примере вы могли бы обратить внимание на неверное место записи Fruit-Loop, Frita и предположить, что неверно сортируются все фамилии, начинающиеся на букву «F». Гипотеза неудачна: она не объясняет неправильное место записи Modula, Mildred и правильную сортировку записей при втором запуске программы. Если данные не соответствуют гипотезе, не игнорируйте их - подумайте, почему они ей не соответствуют, и сформулируйте новую гипотезу.

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

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

Проверяйте код при помощи блочных тестов Какпра- перекрешая сшлка Среды

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

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

те для изолированного тестирования фрагментов кода блоч- блочные тесты в среду тестирования раздела 22.4.

ные тесты.

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

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

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



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

Воспроизведение ошибки разными способами помогает диагностировать причину ошибки (рис. 23-1). Как только вы решили, что причина дефекта ясна, выполните тест, который сам не должен вызывать ошибку, но напоминает тесты, приводящие к ошибке. Если ошибка при этом все же возникает, значит, вы еще не полностью поняли проблему. Причиной ошибки часто становится комбинация факторов, поэтому попытка диагностировать проблему при помощи только одного теста часто не приводит к обнаружению корня проблемы.

Программа „ Программа

Первый тест


Программа



Второй тест

Последующие тесты Третий тест

Рис. 23-1- Чтобы точно определить причину ошибки, попробуйте воспроизвести ошибку разными способами

Генерируйте больше данных для формулирования большего числа гипотез

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

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

Используйте «мозговой штурм» для построения нескольких гипотез Не

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

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



0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 [176] 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294



0.0072