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

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

му из законов Мерфи, программа потерпит крах тогда, когда это причинит наибольший ущерб.

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

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

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

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

Вот пример:

Пример программы, поток данных которой мы протестируем (Java)

if ( Condition 1 ) { X = а;

else { X = b;

if ( Condition 2 ) { у = X + 1;

else {

у = X - 1;

Для покрытия каждого пути выполнения этой программы нам нужен один тест, при котором условие Condition 1 истинно, и один - при котором оно ложно, а также аналогичные тесты для условия Condition 2. Эти ситуации можно охватить двумя тестами: (Condition 1=Тгие, Condition 2=Тгие) и (Condition l=False, Condition 2=False). Два этих теста - все, что нужно для выполнения требований структурированного базисного тестирования, а также для тестирования всех определений переменных; эти тесты автоматически обеспечивают слабую форму тестирования, основанного на потоках данных.

Однако для покрытия всех комбинаций «определение - использование» этого мало. На текущий момент у нас есть тесты тех случаев, когда условия Condition 1 и Condition 2 истинны и когда оба они ложны:



X = а у = X + 1 и

X = b

у = X - 1

Но у нас есть еще две комбинации «определение - использование»: (1) л: = а, после чего = X - 1 и (2) X = после чего j; = х + LB данном примере эти комбинации можно покрыть, добавив еще два теста: (Condition 1=Тгие, Condition 2=False) и (Condition l=False, Condition 2=True).

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

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

Номер теста Описание теста

7 Определение переменной companyRetirement в строке 12 и использование в строке 26. Этот случай может не покрываться имеющимися тестами.

8 Определение переменной companyRetirement в строке 12 и использование в строке 31. Этот случай может не покрываться имеющимися тестами.

9 Определение переменной companyRetirement в строке 17 и использование в строке 31. Этот случай может не покрываться имеющимися тестами.

Выполнив тестирование, основанное на потоках данных, несколько раз, вы начнете чувствовать, какие тесты нужны, а какие уже реализованы. В случае сомнений ищите все комбинации «определение - использование». Это может показаться слишком объемной работой, но так вы точно найдете все случаи, не охваченные базисным тестированием.

Разделение на классы эквивалентности

Хороший тест должен покрывать широкий диапазон вход- «рщтш шш Разряе-

ных данных Если два теста приводят к обнаружению одних нив на шссы эквиашнтнос*

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

«разделения на классы эквивалентности» формализует эту * книгах, укашных 9 раз-

деле «Дополнительные рсур-идею и помогает уменьшить число нужных тестов. jJJ

Подходящее место для разделения на классы эквивалентности - строка 7 уже известного нам листинга, в которой проверяется условие memployeefID JgovemmentRetirementWitbbeld < MAX G0VT RETIREMENT. Это условие



делит все значения memployeef ID ].governmentRetirement Withheld на два класса эквивалентности: значения, которые меньше константы МАХ GOVT RETIREMENT, и значения, которые больше или равны ей. В других частях программы могут использоваться другие классы эквивалентности, что может потребовать тестирования более двух значений т етр1оуее[ID ].governmentRetirementWithheld, но в этой части программы нужно проверить только два значения.

Размышление о разделении на классы эквивалентности не скажет вам много нового о программе, если вы уже покрыли ее базисным тестированием и тестированием, основанным на потоках данных. Однако оно очень полезно, если вы смотрите на программу «извне» (с точки зрения спецификации, а не исходного кода) или если данные сложны, а эта сложность плохо отражена в логике программы.

Угадывание ошибок

пш1шг»ш»гиаг\г Формальные методики тестирования хорошие программи-

ческих методиках т 12 дополняют менее формальными эвристическими методиками. Одна из них - угадывание ошибок (error guessing). Термин «угадывание ошибок» - довольно примитивное название вполне разумной идеи, подразумевающей создание тестов на основе обдуманных предположений о вероятных источниках ошибок.

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

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

Анализ граничных условий

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

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

Меньше Мах Мах Больше Мах 1 I I I I

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

Фрагмент кода, для которого мы подсчитывали число тестов, содержит проверку т етр1оуее[ ID ]governmentRetirementWithheld < MAXGOVT RETIREMENT. Согласно принципам анализа граничных условий следует изучить три случая:



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.0023