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

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

Разработчики часто имеют слишком оптимистичное представление о покрытии кода тестами Как правило, программисты считают, что они достигают 95%-го покрытия кода тестами, но на самом деле они обычно достигают в лучшем случае примерно 80%-го покрытия, в худшем - 30%-го, а в среднем - где-то на 50-60% [данные Бориса Бейзера (Boris Beizer) в Johnson, 1994].

Разработчики часто упускают из виду более сложные аспекты покрытия кода тестами Большинство разработчиков считают тип покрытия кода тестами, известный как «100%-е покрытие операторов», адекватным. Это хорошее начало, но такого покрытия едва ли достаточно. Лучший тип покрытия - так называемое «100%-е покрытие ветвей», требующее, чтобы каждой переменной каждого предиката при тестировании было присвоено хотя бы одно истинное и одно ложное значение (подробнее об этом см. раздел 22.3).

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

22.3. Приемы тестирования

Почему невозможно доказать корректность программы, протестировав ее? Чтобы доказать полную работоспособность программы, вы должны были бы протестировать ее со всеми возможными входными значениями и их комбинациями. Даже в случае самой простой программы такое предприятие оказалось бы слишком масштабным. Допустим, ваша программа принимает фамилию, адрес и номер телефона, а затем сохраняет их в файле. Очевидно, что это простая программа - гораздо проще, чем те, о корректности которых приходится беспокоиться в действительности. Предположим далее, что фамилии и адреса могут иметь длину 20 символов, каждый из которых может иметь одно из 26 возможных значений. Число возможных комбинаций входных данных было бы следующим:

Фамилия 2б° (20 символов; 26 вариантов каждого символа)

Адрес 26 (20 символов; 26 вариантов каждого символа)

Номер телефона 10(10 цифр; 10 вариантов каждой цифры)

Общее число комбинаций = 26 260 10 » 10

Даже при таком относительно небольшом объеме входных данных вам пришлось бы выполнить 10 тестов. Если бы Ной, высадившись из ковчега, начал тестировать эту программу со скоростью триллион тестов в секунду, на текущий момент он был бы далек от выполнения даже 1% тестов. Очевидно, что при вводе более реалистичного объема данных исчерпывающее тестирование всех комбинаций стало бы еще менее «осуществимым».



Неполное тестирование

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

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

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

Структурированное базисное тестирование

Несмотря на пугающее название, в основе структурированного базисного тестирования (structured basis testing) лежит довольно простая идея: вы должны протестировать каждый оператор программы хотя бы раз. Если оператор является логическим, таким как if или while, вы должны учесть сложность выражения внутри if или while, чтобы оператор был протестирован полностью. Самый легкий способ покрыть все базисные элементы предполагает подсчет числа возможных путей выполнения программы и создание минимального набора тестов, проверяющих каждый путь.

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

Минимальное число тестов, нужных для базисного тести-

прехршиш! осыт Зта про-

рования, найти очень просто:

1. начните с 1 для последовательного пути выполнения оценки спожностй (см. подаз-метода; Ал «Как измерить ттш%

2. прибавьте 1 для каждого из ключевых слов if while, repeat, PWta \Щ. for, and и or или их аналогов;

3. прибавьте 1 для каждого блока case; если отсутствует блок, используемый по умолчанию, прибавьте еще 1.

Вот пример:

Простой пример подсчета числа путей выполнения программы (Java)

- Начинаем счет: «1» - сам метод.

Statementl; Statement2;



- «2» - оператор if.

->if ( X < 10 ) { Statements;

Statement4;

В этом случае мы начинаем с 1 и встречаем один оператор if, получая в итоге 2. Это значит, что для покрытия всех путей выполнения этого кода вам нужно создать минимум два теста, соответствующих следующим условиям:

операторы, контролируемые оператором if, выполняются (х < 10);

операторы, контролируемые оператором if не выполняются (х >= 10).

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


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

Пример подсчета числа тестов, нужных для базисного тестирования (Java)

- «1» - сам метод.

->1 Вычисление фактической заработной платы. 2 totalWithholdings = 0; 3

г- «2» - цикл for.

->4 for ( id = 0; id < numEmployees; id++ ) { 5

6 Вычисление суммы взноса в фонд социального страхования. J- «3» оператор if.

>7 if ( m employee[ id ].governmentRetirementWithheld < MAX GOVT RETIREMENT ) {

8 governmentRetirement = ComputeGovernmentRetirement( m employee[ id ] );

9 } 10

11 Взнос в пенсионный фонд компании по умолчанию не взимается.



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