Правильная ссылка на эту страницу
http://az-design.ru/Support/SoftWare/l/GlassRob/03f32.shtml

ФАКТ 32

Факт 32
       Оказывается, что в ПО о котором типичный программист думает, что оно тщательно протестированное нередко проверено выполнение лишь 55-60% логических путей. Применение автоматизированных средств, таких как анализаторы покрытия, позволяет повысить эту долю примерно до 85-90%. Протестировать 100% логических путей ПО практически невозможно.

Обсуждение
       В литературе описана масса подходов к тестированию ПО. (Под тестированием здесь понимается исполнение программного кода, призванное выявить ошибки в нем.) Но описание, классификация и даже пропаганда этих подходов не очень-то согласованны. Вот эти ПОДХОДЫ:
       — Тестирование на основе требований (requirements-driven testing), призванное проверить, все ли требования выполнены.
       — Структурное тестирование (structure-driven testing), призванное проверить, все ли блоки программы функционируют надлежащим образом.
       — Статистическое тестирование (statistics-driven testing); проводится выборочно, чтобы проверить, как долго или насколько хорошо может выполняться программа.
       — Тестирование, ориентированное на риски (risk-driven testing), позволяет удостовериться в том, что основные риски нашли должное отражение.
       Здесь речь пойдет о структурном тестировании. Но, прежде чем приступить к его обсуждению, поговорим немного о том, как следует применять эти тестовые методики.
       Без тестирования на основе требований не обойтись, но его одного мало. Такому тестированию, причем тщательному, должно подвергаться все ПО. Однако оно никогда не бывает исчерпывающим, отчасти из-за того, что количество самих требований по ходу создания продукта растет лавинообразно, о чем уже говорилось. И эти добавленные проектные требования преобразуются в код, поэтому если учитывать только исходные требования, то многие участки программного кода просто не будут протестированы.
       Следовательно, структурное тестирование необходимо. Чтобы проверить все добавленные фрагменты, которые не очень-то хорошо связаны с исходными требованиями, обязательно следует попытаться протестировать все структурные элементы готовой программы. Слово "попытаться" употреблено намеренно — потом мы увидим, что протестировать всю структуру невозможно. И хотя самые удачные структурные методы основаны на логическом делении, у подхода, задействующего поток данных (а не логику исполнения), есть свои сторонники, - поэтому мы говорим "структурные элементы".
       Обратите внимание, что пока я почти не говорю о статистическом тестировании и тестировании, учитывающем риски. Первое подходит, когда требуется вселить в потенциальных пользователей уверенность, что программный продукт готов к промышленной эксплуатации, а второе незаменимо для проектов с высокими рисками, в которых важно удостовериться, что все риски известны и находятся под контролем. Но тщательное структурное тестирование и тестирование, основанное на требованиях сложны, поэтому к этим другим подходам (статистическому и учитывающему риски) стараются прибегать только в проектах с критичными или необычными требованиями к надежности. Более подробную информацию о статистическом тестировании и подходе, связанном с рисками, можно найти, например, в моей книге [Glass, 1992].
       Я исхожу из предположения, что структурное тестирование связано с логическими сегментами, а не с потоками данных (структура, связанная с потоками данных, значительно усложняет процесс тестирования и редко применяется на практике). Даже если сказать, что логические сегменты должны быть единицей тестирования, остается вопрос о том, что такое логический сегмент. Мы могли бы проверить каждую инструкцию, логический путь или каждый модуль/компонент. Тестирование модулей/компо-нентов как правило неразрывно связано со структурным тестированием, но его опять же недостаточно (поскольку модуль или компонент содержит массу фрагментов кода, подлежащего тестированию). И оказывается, что даже тестирование на уровне инструкций (statement-level testing) не обеспечивает необходимой полноты тестирывания. (Это открытие противоречит зравому смыслу и требует более подробного обсуждения, а здесь я ограничиваюсь констатацией факта. Чтобы понять, почему тестирование на уровне инструкций не настолько надежно, как тестирование логических путей, обратитесь, например, к работе [Glass, 1992].)
       Поэтому сосредоточим внимание на логических путях программы, о попытках полностью протестировать которые я буду говорить в оставшейся части данного факта. (При этом проверяются пути исполненеия, определяемые логическим ветвлением, поэтому такое тестирование нередко называют тестированием ветвей (branch testing) . Я предпочитаю говорить о логических путях, поскольку мы тестируем не ветвление, а код в ветвях исполнения.)
       Теперь поговорим о структурном тестировании и покрытии. Итак, если программист говорит, что код тщательно протестирован, это нередко означает, что на самом деле были выполнены лишь от 55% до 60% логических путей [Glass, 1992]. Это обстоятельство, как и большая часть материала данного факта, свидетельствует о сложности программного продукта и показывает, как мало даже создатели программного кода знают о том, что они сделали. Специалисты по методам тестирования логических путей говорят, что инструменты, помогающие определить уровень покрытия структурного теста, (они называются анализаторами тестового покрытия), позволяют увеличить этот показатель до 85-90% [Glass, 1992]. Часто, что опять же противоречит здравому смыслу, увеличить уровень тестирования логических путей до 100% просто невозможно (из-за таких "мертвых зон", как недоступные логические пути, обработчики исключительных ситуаций, которые трудно заставить сработать, и т.д.). Те же самые эксперты выступают за применение инспекций, чтобы охватить логические пути, которые не были исполнены. (За более подробной информацией об инспекциях обратитесь к разделу "Инспекции и экспертиза", начинающегося с Факта 37.)
       Итак, мы видим, что изобилие подходов к тестированию не компенсирует сложности типичного программного продукта, которая и препятствует проведению" исчерпывающего тестирования. Из-за этого: а) тестирование представляет собой компромисс, и жизненно важно сделать правильный выбор, и б) неудивительно, что большая часть важных программных продуктов выпускается с ошибками (ожидать, что программа не будет содержать ошибок - большая наивность).

Полемика
       О тестировании программ накоплена масса знаний, но на практике оно выглядит на удивление элементарным. Тестирование большинства программ основывается на списке требований, и очень малая их доля подвергается систематическому структурному тесгированию. (Большинство программистов делают попытку обратиться к структурным аспектам ПО, которое они создали, понимая, что тестирования на основе требований недостаточно, но они редко применяют какие-либо инструменты структурного анализа, чтобы узнать, насколько хорошо им это удалось.) Статистические методы и подходы, связанные с рисками, применяются на практике столь же редко.
       Дело здесь заключается не столько в полемике по поводу этого факта и его следствий, сколько в том, что этапу тестирования жизненного цикла практически всегда уделяется слишком мало внимания. Объяснить, почему это так, увы, нетрудно. Команда разработчиков, как мы уже видели, по рукам и ногам связана нехваткой ресурсов и невыполнимыми сроками. Катастрофа со сроками наступает на более поздних этапах жизненного цикла, как раз тогда, когда ведется тестирование. Поэтому в процессе тестирования пренебрегают тем, чем на более ранних этапах жизненного цикла пренебрегают редко. Дело не только в том, что редко применяются анализаторы тестового покрытия (мы вернемся к этому позже), но и в том, что ни специалисты-практики, ни их менеджеры, похоже, не заинтересованы в том, чтобы потратить деньги на приобретение этих инструментов. Многие даже не знают об их существовании.
       Серьезная полемика по поводу недостаточного структурного тестирования в большинстве программных проектов должна быть Однако ее нет, и это красноречивее всяких слов говорит о том, как обстоят дела в индустрии ПО начала двадцать первого столетия.
       Все остальные споры, связанные с этим фактом, относятся к идее создания ПО, не содержащего ошибок. Многие эксперты программирования заявляют, что это возможно, и атакуют тех, кто не смог этого сделать. Но из того, что было сказано в данном разделе, должно быть очевидно, что добиться этой высокой цели можно лишь в самых маленьких проектах. Пожалуй, важно отказаться от обреченных на неудачу попыток создать ПО без ошибок, чтобы сконцентрироваться на более реалистичных и достижимых целях (например, на создании ПО без критических ошибок)

Источник
       Методы тестирования ПО подробно описаны мной в работе, указанной в следующем разделе "Ссылка" (и в других местах), и хотя с момента написания книги прошло немало времени, я продолжаю считать, что подробное обсуждение данного факта (и некоторых из последующих), приведенное там, заслуживает серьезного внимания.

Ссылка
       — Glass, Robert L. 1992. Building Quality Software. Englewood Cliffs, NJ: Prentice-Hall.


<<< Пред. Оглавление
Glass Robert L.
Начало раздела
След. >>>



<<< Пред. Оглавление
Начало раздела
След. >>>

Дата последнего изменения:
Thursday, 21-Aug-2014 09:10:55 MSK


Постоянный адрес статьи:
http://az-design.ru/Support/SoftWare/l/GlassRob/03f32.shtml