Руководство по стилю программирования и конструированию по
Скачать 7.6 Mb.
|
ГЛАВА 22 Тестирование, выполняемое разработчиками 519 не привело к появлению новых дефектов. Тестирование, призванное гарантиро- вать, что программа не сделала шаг назад, или не «регрессировала», называется «регрессивным». Почти невозможно создать высококачественную программу, если вы не можете си- стематично проводить ее повторного тестирования после внесения изменений. Если после каждого изменения выполнять другие тесты, вы не сможете с уверенностью сказать, что в программу не были внесены новые дефекты. Так что при регрессив- ном тестировании нужно каждый раз выполнять одни и те же тесты. По мере разви- тия системы можно добавлять новые тесты, но сохранять при этом и старые. Автоматизированное тестирование Единственный практичный способ управления регрессивным тестиро- ванием — его автоматизация. Многократное выполнение одних и тех же тестов, приводящих к тем же результатам, вводит людей в транс. Они утрачивают концентрацию и начинают упускать ошибки, что сводит на нет эф- фективность регрессивного тестирования. Гуру тестирования Борис Бейзер сооб- щает, что уровень ошибок, допускаемых при тестировании вручную, сравним с уровнем ошибок в самом тестируемом коде. По его оценкам, при тестировании, проводимом вручную, должным образом выполняется лишь около половины всех тестов (Johnson, 1994). Преимущества автоматизированного тестирования таковы. 쐽 При автоматизированном тестировании вероятность допустить ошибку ниже, чем при тестировании вручную. 쐽 Автоматизировав тестирование, вы сможете легко адаптировать его к другим компонентам системы. 쐽 Автоматизация тестирования позволяет выполнять тесты гораздо чаще. Авто- матизация тестирования — один из базовых элементов интенсивных методик тестирования, таких как ежедневная сборка программы, дымовое тестирова- ние и экстремальное программирование. 쐽 Автоматизированное тестирование способствует максимально раннему обна- ружению проблем, что обычно минимизирует объем работы, нужной для ди- агностики и исправления проблемы. 쐽 Способствуя более быстрому обнаружению дефектов, внесенных в код при его изменении, автоматизированное тестирование снижает вероятность того, что вам придется позднее заняться крупномасштабным исправлением кода. 쐽 Автоматизированное тестирование особенно полезно в новых изменчивых технологических средах, поскольку оно позволяет быстрее узнавать об изменениях среды. Многие инструменты, используемые для автоматизации тестирования, позволяют создавать тестовые леса, генери- ровать входные и регистрировать выходные данные и сравнивать действитель- ные выходные данные с ожидаемыми. Для выполнения этих функций можно ис- пользовать инструменты, обсуждавшиеся в предыдущем разделе. Перекрестная ссылка О связи между зрелостью технологий и методами разработки см. раз- дел 4.3. 520 ЧАСТЬ V Усовершенствование кода 22.7. Протоколы тестирования Обеспечить повторяемость процесса тестирования недостаточно — вы должны оценивать и проект, чтобы можно было точно сказать, улучша- ется он в результате изменений или ухудшается. Вот некоторые катего- рии данных, которые можно собирать с целью оценки проекта: 쐽 административное описание дефекта (дата обнаружения, сотрудник, сообщив- ший о дефекте, номер сборки программы, дата исправления); 쐽 полное описание проблемы; 쐽 действия, предпринятые для воспроизведения проблемы; 쐽 предложенные способы решения проблемы; 쐽 родственные дефекты; 쐽 тяжесть проблемы (например, критическая проблема, «неприятная» или кос- метическая); 쐽 источник дефекта: выработка требований, проектирование, кодирование или тестирование; 쐽 вид дефекта кодирования: ошибка занижения или завышения на 1, ошибка при- сваивания, недопустимый индекс массива, неправильный вызов метода и т. д.; 쐽 классы и методы, измененные при исправлении дефекта; 쐽 число строк, затронутых дефектом; 쐽 время, ушедшее на нахождение дефекта; 쐽 время, ушедшее на исправление дефекта. Собирая эти данные, вы сможете подсчитывать некоторые показатели, позволя- ющие сделать вывод об изменении качества проекта: 쐽 число дефектов в каждом классе; все числа целесообразно отсортировать в порядке от худшего класса к лучшему и, возможно, нормализовать по размеру класса; 쐽 число дефектов в каждом методе, все числа целесообразно отсортировать в порядке от худшего метода к лучшему и, возможно, нормализовать по разме- ру метода; 쐽 среднее время тестирования в расчете на один обнаруженный дефект; 쐽 среднее число обнаруженных дефектов в расчете на один тест; 쐽 среднее время программирования в расчете на один исправленный дефект; 쐽 процент кода, покрытого тестами; 쐽 число дефектов, относящихся к каждой категории тяжести. Личные протоколы тестирования Кроме протоколов тестирования уровня проекта, вы можете хранить и личные протоколы тестирования. Можете включать в них контрольные списки ошибок, которые вы допускаете чаще всего, и указывать время, затрачиваемое вами на написание кода, его тестирование и исправление ошибок. ГЛАВА 22 Тестирование, выполняемое разработчиками 521 Дополнительные ресурсы Федеральные законы об объективности информации застав- ляют меня признаться в том, что в нескольких других кни- гах тестирование рассматривается подробнее, чем в этой главе. Например, в них можно найти материалы о тестировании системы и тес- тировании методом «черного ящика», которых мы не касались. Кроме того, в этих книгах более глубоко освещаются вопросы тестирования, выполняемого разра- ботчиками. В них обсуждаются формальные подходы к тестированию (такие как создание причинно-следственных диаграмм), а также детали создания независи- мой организации, занимающейся тестированием. Тестирование Kaner, Cem, Jack Falk, and Hung Q. Nguyen. Testing Computer Software, 2d ed. New York, NY: John Wiley & Sons, 1999. Наверное, это лучшая книга по тестированию ПО. Приведенная в ней информация касается в первую очередь тестирования программ, которые будут использоваться большим числом людей (например, крупных Web- сайтов и приложений, продаваемых в магазинах), но полезна и в общем. Kaner, Cem, James Bach, and Bret Pettichord. Lessons Learned in Software Testing. New York, NY: John Wiley & Sons, 2002. Эта книга хорошо дополняет предыдущую. Она разделена на 11 глав, включающих 250 уроков, изученных самими авторами. Tamre, Louise. Introducing Software Testing. Boston, MA: Addison-Wesley, 2002. Эта несложная книга ориентирована на разработчиков, которым нужно понять тес- тирование. Несмотря на название («Введение в тестирование ПО»), некоторые из приведенных в книге сведений будут полезны и опытным тестировщикам. Whittaker, James A. How to Break Software: A Practical Guide to Testing. Boston, MA: Addison-Wesley, 2002. В этой книге описаны 23 вида атак, которые тестировщики могут использовать для нарушения работы ПО, и приведены примеры каждой атаки с применением популярных программных пакетов. Из-за оригинального подхо- да эту книгу можно рассматривать и как основной источник информации о тес- тировании, и как дополнение других книг. Whittaker, James A. «What Is Software Testing? And Why Is It So Hard?» IEEE Software, January 2000, pp. 70–79. В этой статье можно найти хорошее введение в вопросы тестирования ПО и объяснение некоторых проблем, связанных с эффективным тестированием. Myers, Glenford J. The Art of Software Testing. New York, NY: John Wiley, 1979. Эта клас- сическая книга по тестированию ПО издается до сих пор (хотя и стоит немало). Ее содержание довольно простое: тестирование, основанное на самооценке; пси- хология и экономика тестирования программ; анализ и обзоры программ; про- ектирование тестов; тестирование классов; тестирование более высокого поряд- ка; отладка; инструменты тестирования и другие методики. Книга лаконична (177 страниц) и легко читается. Приведенный в ее начале тест поможет вам начать думать, как тестировщик, и продемонстрирует все разнообразие способов нару- шения работы кода. http://cc2e.com/2203 522 ЧАСТЬ V Усовершенствование кода Тестовые леса Bentley, Jon. «A Small Matter of Programming» in Programming Pearls, 2d ed. Boston, MA: Addison-Wesley, 2000. В этом эссе приведены хорошие примеры тестовых лесов. Mackinnon, Tim, Steve Freeman, and Philip Craig. «Endo-Testing: Unit Testing with Mock Objects», eXtreme Programming and Flexible Processes Software Engineering - XP2000 Conference, 2000. Первая работа, посвященная использованию поддельных объек- тов при тестировании, выполняемом разработчиками. Thomas, Dave and Andy Hunt. «Mock Objects» IEEE Software, May/June 2002. Эта ста- тья представляет собой удобочитаемое введение в использование поддельных объектов. www.junit.org. Это сайт поддержки разработчиков, использу- ющих среду JUnit. Аналогичные сайты см. по адресам cpp- unit.sourceforge.net и nunit.sourceforge.net. Разработка с изначальными тестами Beck, Kent. Test-Driven Development: By Example. Boston, MA: Addison-Wesley, 2003. Бек описывает «разработку через тестирование» — подход, предусматривающий первоначальное создание тестов и последующее написание кода, удовлетворяю- щего тестам. Хотя местами Бек впадает в евангелический тон, его советы очень полезны, а сама книга лаконична и попадает точно в цель. Стоит отметить, что она включает серьезный пример, для которого приводится реальный код. Соответствующие стандарты IEEE Std 1008-1987 (R1993) — стандарт блочного тестирования ПО. IEEE Std 829-1998 — стандарт документирования тестов ПО. IEEE Std 730-2002 — стандарт планирования контроля качества ПО. Контрольный список: тесты 쏔 Каждому ли требованию, относящемуся к классу или методу, соответствует отдельный тест? Каждому ли аспекту проектирования, относящемуся к классу или методу, соответствует отдельный тест? Каждая ли строка кода протестирована хотя бы одним тестом? Проверили ли вы это, подсчитав минимальное число тестов, нужное для выполнения каждой строки кода? Каждый ли путь «определение — использование» в потоке данных протес- тирован хотя бы одним тестом? Проверили ли вы код на наличие в потоке данных путей, которые обычно ошибочны, таких как «определение — определение», «определение — вы- ход» и «определение — уничтожение»? Использовали ли вы список частых ошибок для написания тестов, направ- ленных на обнаружение ошибок, которые часто встречались в прошлом? Протестировали ли вы все простые граничные условия: максимальные, минимальные и граничные условия с завышением или занижением на 1? http://cc2e.com/2217 http://cc2e.com/2210 ГЛАВА 22 Тестирование, выполняемое разработчиками 523 Протестировали ли вы сложные граничные условия, т. е. комбинации вход- ных данных, которые могут приводить к слишком малому или большому значению вычисляемой переменной? Тестируете ли вы код на предмет неверных видов данных, таких как отри- цательное число сотрудников в программе расчета заработной платы? Тестируете ли вы код с использованием типичных средних значений? Тестируете ли вы минимальные нормальные конфигурации? Тестируете ли вы максимальные нормальные конфигурации? Тестируете ли вы совместимость со старыми данными? Тестируете ли вы код, работающий со старым оборудованием и старыми версиями операци- онной системы, а также интерфейсы со старыми версиями других программ? Позволяют ли тесты легко проверить результаты вручную? Ключевые моменты 쐽 Тестирование, выполняемое разработчиками, — один из важнейших элемен- тов полной стратегии тестирования. Независимое тестирование не менее важно, но оно не является предметом этой книги. 쐽 Написание тестов до написания кода требует примерно того же времени и тех же усилий, что и создание тестов после кода, но сокращает циклы регистра- ции — отладки — исправления дефектов. 쐽 Даже если учесть, что тестирование имеет массу разновидностей, его все рав- но следует считать лишь одним из элементов хорошей программы контроля качества. Высококачественные методики разработки, позволяющие свести к минимуму число дефектов в требованиях и проектах, играют не менее, а то и более важную роль. Методики совместной разработки характеризуются не меньшей эффективностью обнаружения ошибок, чем тестирование, к тому же они позволяют находить другие ошибки. 쐽 Опираясь на базисное тестирование, анализ потоков данных, анализ гранич- ных условий, классы плохих и классы хороших данных, вы можете создать много тестов детерминированным образом. Методика угадывания ошибок укажет вам на некоторые дополнительные тесты. 쐽 Обычно ошибки концентрируются в нескольких наиболее дефектных классах и методах. Найдите такой код, перепроектируйте его и перепишите. 쐽 Для тестовых данных обычно характерна более высокая плотность ошибок, чем для тестируемого кода. Так как поиск ошибок в тестовых данных требует вре- мени, не приводя к какому бы то ни было улучшению кода, эти ошибки более досадны, чем ошибки программирования. Избегайте их, разрабатывая тесты столь же тщательно, что и код. 쐽 Автоматизация тестирования полезна вообще и практически необходима в случае регрессивного тестирования. 쐽 Чтобы процесс тестирования был максимально эффективным, сделайте его регулярным, выполняйте его оценку и используйте получаемую информацию для его улучшения. 524 ЧАСТЬ V Усовершенствование кода Г Л А В А 2 3 Отладка Содержание 쐽 23.1. Общие вопросы отладки 쐽 23.2. Поиск дефекта 쐽 23.3. Устранение дефекта 쐽 23.4. Психологические аспекты отладки 쐽 23.5. Инструменты отладки — очевидные и не очень Связанные темы 쐽 Качество ПО: глава 20 쐽 Тестирование, выполняемое разработчиками: глава 22 쐽 Рефакторинг: глава 24 Отладка — это процесс определения и устранения причин ошибок. Этим она отличается от тестирования, направлен- ного на обнаружение ошибок. В некоторых проектах отладка занимает до 50% общего времени разработки. Многие про- граммисты считают отладку самым трудным аспектом про- граммирования. Но отладка не обязана быть таковой. Если вы будете следо- вать советам, приведенным в этой книге, вам придется отла- живать меньше ошибок. Большинство дефектов будет тривиальными недосмотра- ми и опечатками, которые вы сможете легко находить, читая исходный код или вы- полняя его в отладчике. Что до остальных, более сложных ошибок, то, прочитав эту главу, вы сможете сделать их отладку гораздо более легкой. 23.1. Общие вопросы отладки Покойная Грейс Хоппер (Grace Hopper), контр-адмирал ВМС США и один из ав- торов языка COBOL, утверждала, что слово «bug» появилось в программировании во времена первого крупного цифрового компьютера — Mark I (IEEE, 1992). Раз- бираясь с причинами неисправности компьютера, программисты нашли в нем крупного мотылька, замкнувшего какую-то цепь, и с тех пор вину за все компью- http://cc2e.com/2361 Отлаживать код вдвое сложнее, чем писать. Поэтому, если при написании программы вы ис- пользуете весь свой интеллект, вы по определению недостаточно умны, чтобы ее отладить. Брайан Керниган (Brian W. Kernighan) ГЛАВА 23 Отладка 525 терные проблемы стали сваливать на насекомых. Вне программирования слово «bug» уходит корнями по крайней мере во времена Томаса Эдисона, который ис- пользовал его уже в 1878 году (Tenner, 1997). Забавное слово «bug» вызывает в воображении подобные образы: Однако на самом деле программные дефекты — не организмы, проникающие в код, если его забыли обработать пестицидами. Это ошибки, допущенные програм- мистами, а результаты ошибок обычно больше похожи не на предыдущий рису- нок, а на подобную записку: Отладка и качество ПО Как и тестирование, сама по себе отладка не служит для повышения качества ПО — это способ диагностики дефектов. О качестве нужно заботиться с самого нача- ла работы над программой. Лучший способ создания качественной программы заключается в тщательной выработке требований, грамотном проектировании и применении высококачественных методик кодирования. Отладка — это средство для крайних случаев Различия в эффективности отладки Зачем вообще обсуждать отладку? Разве не все программисты умеют отлаживать программы? Увы, не все. Исследования показали, что опытным программистам для на- хождения тех же ошибок требовалось примерно в 20 раз меньше време- ни, чем неопытным. Более того, некоторые программисты находят больше дефектов и исправляют их грамотнее. Вот результаты классического исследова- ния, в котором профессиональных программистов, обладающих минимум 4-лет- ним опытом, попросили отладить программу с 12 дефектами: 526 ЧАСТЬ V Усовершенствование кода Три самых Три самых быстрых медленных программиста программиста Среднее время отладки (в минутах) 5,0 14,1 Среднее число необнаруженных дефектов 0,7 1,7 Среднее число новых дефектов, 3,0 7,7 внесенных в код при исправлении имеющихся дефектов Источник: «Some Psychological Evidence on How People Debug Computer Programs» (Gould, 1975) Три самых лучших в отладке программиста смогли найти дефекты при- мерно в 3 раза быстрее и внесли в код примерно в 2,5 раза меньше де- фектов, чем три худших. Самый лучший программист обнаружил все дефекты и не внес во время их исправления новых. Самый худший не нашел 4 из 12 дефектов, а при исправлении 8 обнаруженных дефектов внес в код 11 новых. Но ставить точку рано. После первого раунда отладки в коде самых быстрых про- граммистов все еще остались 3,7 дефекта, а в коде самых медленных — 9,4 дефек- та. Ни одна из групп не довела отладку до конца. У меня возник вопрос, что слу- чится, если экстраполировать данные этого исследования на дополнительные циклы отладки. Мои результаты не являются статистически надежными, но они все же интересны. Применив те же показатели обнаружения и некорректного исправления дефектов к дополнительным циклам, я выяснил, что для снижения показателя необнаруженных дефектов до уровня 0,5 дефекта самой быстрой группе понадобились бы в общей сложности 3 цикла отладки, а самой медленной — 14. Если далее учесть, что время выполнения одного цикла отладки этими группами различается почти в 3 раза, мы получим, что самой медленной группе для пол- ной отладки своих программ потребовалось бы в 13 раз больше времени, чем самой быстрой. Аналогичные крупные различия в эффективности отладки показали и другие исследования (Gilb, 1977; Curtis, 1981). Эти данные не только сообщают нам кое-что об отладке, но и подтверждают Главный Закон Контроля Качества ПО: по- вышение качества программы снижает затраты на ее разра- ботку. Лучшие программисты обнаружили больше дефектов за меньшее время и исправили их более корректно. Нет нужды выбирать между качеством, стоимостью и быстротой — они идут рука об руку. Дефекты как возможности обучения О чем говорит наличие дефекта? Ну, если исходить из того, что наличие дефек- тов в программе нежелательно, это говорит о том, что вы не полностью понима- ете программу. Это тревожит. Все-таки, если вы написали программу, она должна делать то, что вам нужно. Если вы не до конца понимаете свои указания компиля- тору, еще чуть-чуть, и вы просто начнете пробовать все, что придет в голову, пока что-то не сработает, т. е. начнете программировать методом проб и ошибок. А раз так, дефекты неизбежны. Вам не нужно учиться исправлять дефекты — вам нуж- но знать, как их избегать. Перекрестная ссылка О связи между качеством ПО и стоимо- стью его разработки см. раздел 20.5. |