Файл: Руководство по стилю программирования и конструированию по.pdf
ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 30.11.2023
Просмотров: 777
Скачиваний: 2
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
490
ЧАСТЬ V Усовершенствование кода
Г Л А В А 2 2
Тестирование, выполняемое
разработчиками
Содержание
쐽
22.1. Тестирование, выполняемое разработчиками,
и качество ПО
쐽
22.2. Рекомендуемый подход к тестированию, выполня- емому разработчиками
쐽
22.3. Приемы тестирования
쐽
22.4. Типичные ошибки
쐽
22.5. Инструменты тестирования
쐽
22.6. Оптимизация процесса тестирования
쐽
22.7. Протоколы тестирования
Связанные темы
쐽
Качество ПО: глава 20
쐽
Методики совместного конструирования: глава 21
쐽
Отладка: глава 23
쐽
Интеграция: глава 29
쐽
Предварительные условия конструирования: глава 3
Тестирование — самая популярная методика повышения качества, подкрепленная многими исследованиями и богатым опытом разработки коммерческих прило- жений. Существует множество видов тестирования: одни обычно выполняют сами разработчики, а другие — специализированные группы. Виды тестирования пе- речислены ниже.
쐽
Блочным тестированием называют тестирование полного класса, метода или небольшого приложения, написанного одним программистом или группой,
выполняемое отдельно от прочих частей системы.
쐽
Тестирование компонента — это тестирование класса, пакета, небольшого при- ложения или другого элемента системы, разработанного несколькими програм- мистами или группами, выполняемое в изоляции от остальных частей системы.
http://cc2e.com/2261
ГЛАВА 22 Тестирование, выполняемое разработчиками
491
쐽
Интеграционное тестирование — это совместное выполнение двух или бо- лее классов, пакетов, компонентов или подсистем, созданных несколькими программистами или группами. Этот вид тестирования обычно начинают про- водить, как только созданы два класса, которые можно протестировать, и про- должают до завершения работы над системой.
쐽
Регрессивным тестированием называют повторное выполнение тестов, направ- ленное на обнаружение дефектов в программе, уже прошедшей этот набор тестов.
쐽
Тестирование системы — это выполнение ПО в его окончательной конфигу- рации, интегрированного с другими программными и аппаратными система- ми. Предметом тестирования в этом случае являются безопасность, произво- дительность, утечка ресурсов, проблемы синхронизации и прочие аспекты,
которые невозможно протестировать на более низких уровнях интеграции.
В этой главе «тестированием» я называю тестирование, выполняемое разработ- чиками, которое обычно включает три первых вида тестирования из приведен- ного списка, но иногда может включать также регрессивное тестирование и тес- тирование системы. Многие другие виды тестирования обычно выполняют не раз- работчики, а специализированный персонал: в качестве примеров можно приве- сти бета-тестирование, тестирование системы на предмет одобрения заказчиком,
тестирование производительности, тестирование конфигурации, платформенное тестирование, тестирование в стрессовом режиме, тестирование удобства исполь- зования и т. д. Эти виды тестирования мы рассматривать не будем.
Тестирование обычно разделяют на две обширных категории: «тестиро- вание методом черного ящика» и «тестирование методом белого (про- зрачного) ящика». В первом случае тестировщик не владеет сведениями о внутренней работе тестируемого элемента. Очевидно, что это не так, если вы тестируете собственный код. При тестировании методом белого ящика внутрен- няя реализация тестируемого элемента тестировщику известна. Тестируя собствен- ный код, вы используете именно этот вид тестирования. Оба вида имеют свои плюсы и минусы; в данной главе основное внимание уделяется тестированию методом белого ящика, потому что именно его выполняют сами разработчики.
Порой термины «тестирование» и «отладка» используют взаимозаменяемо, но внимательные программисты различают два этих процесса. Тестирование — это средство обнаружения ошибок, тогда как отладка является средством поиска и устранения причин уже обнаруженных ошибок. Эта глава посвящена исключитель- но обнаружению ошибок. Об исправлении ошибок см. главу 23.
Тема тестирования не ограничивается тестированием во время конструирования.
Информацию о тестировании системы, тестировании в стрессовом режиме, тес- тировании методом черного ящика и других вопросах, ориентированных на спе- циалистов по тестированию, можно найти в работах, указанных в разделе «До- полнительные ресурсы» в конце главы.
492
ЧАСТЬ V Усовершенствование кода
22.1. Тестирование, выполняемое
разработчиками, и качество ПО
Тестирование — важная часть любой программы контроля качества, а зачастую и единственная. Это печально, так как разнообразные методики совместной разработки позволя- ют находить больше ошибок, чем тестирование, и в то же время обходятся более чем вдвое дешевле в расчете на одну обнаруженную ошибку (Card, 1987; Russell,
1991; Kaplan, 1995). Каждый из отдельных этапов тестирования (блочное тести- рование, тестирование компонентов и интеграционное тестирование) обычно позволяет найти менее 50% ошибок. Комбинация этапов тестирования часто при- водит к обнаружению менее 60% ошибок (Jones, 1998).
Если у программиста спросить, какой из этапов разработ- ки ПО менее всего похож на другие, он наверняка ответит:
«Тестирование». По ряду описанных ниже причин большин- ство разработчиков испытывают при тестировании затруд- нения.
쐽
Цель тестирования противоположна целям других эта- пов разработки. Его целью является нахождение ошибок.
Успешным считается тест, нарушающий работу ПО. Все ос- тальные этапы разработки направлены на предотвращение ошибок и недопу- щение нарушения работы программы.
쐽
Тестирование никогда не доказывает отсутствия ошибок. Если вы тщательно протестировали программу и обнаружили тысячи ошибок, значит ли это, что вы нашли все ошибки или в программе все еще остались тысячи других оши- бок? Отсутствие ошибок может указывать как на безупречность программы, так и на неэффективность или неполноту тестов.
쐽
Тестирование не повышает качества ПО — оно указывает на качество програм- мы, но не влияет на него. Стремление повысить качество ПО за счет увеличе- ния объема тестирования подобно попытке снижения веса путем более час- того взвешивания. То, что вы ели, прежде чем встать на весы, определяет, сколько вы будете весить, а использованные вами методики разработки ПО определя- ют, сколько ошибок вы обнаружите при тестировании. Если вы хотите снизить вес, нет смысла покупать новые весы — измените вместо этого свой рацион.
Если вы хотите улучшить ПО, вы должны не тестировать больше, а програм- мировать лучше.
쐽
Тестирование требует, чтобы вы рассчитывали найти ошибки в сво- ем коде. В противном случае вы, вероятно, на самом деле их не найдете,
но это будет всего лишь самоисполняющимся пророчеством. Если вы за- пускаете программу в надежде, что она не содержит ошибок, их будет слиш- ком легко не заметить. В исследовании, которое уже стало классическим, Глен- форд Майерс попросил группу опытных программистов протестировать про- грамму, содержащую 15 известных дефектов. В среднем программисты нашли лишь 5 из 15 ошибок. Лучший программист обнаружил только 9. Главной при- чиной неэффективного обнаружения ошибок было недостаточно вниматель-
Перекрестная ссылка Об обзо- рах ПО см. главу 21.
Программы — не люди, а ошиб- ки — не микробы: программа не может нахвататься ошибок, об- щаясь с другими дефектными программами. Ошибки всегда допускают программисты.
Харлан Миллз
(Harlan Mills)
ГЛАВА 22 Тестирование, выполняемое разработчиками
493
ное изучение ошибочных выходных данных. Ошибки были видны, но програм- мисты их не заметили (Myers, 1978).
Вы должны надеяться обнаружить ошибки в своем коде. Это может казаться неес- тественным, но лучше уж найти свои ошибки самому, иначе вам на них укажет кто-то другой.
Один из важнейших вопросов состоит в том, сколько времени разработчикам следует уделять тестированию в типичном проекте. Часто говорят, что на все те- стирование уходит 50% времени разработки системы, но это может ввести в за- блуждение. Во-первых, это число охватывает и тестирование, и отладку; само же тестирование занимает меньше времени. Во-вторых, это число отражает время,
которое обычно тратят на тестирование, а не время, которое следует тратить.
В-третьих, это число включает и тестирование, выполняемое разработчиками, и независимое тестирование.
В зависимости от объема и сложности проекта тестированию, выполняемому разработчиками, вероятно, следует посвящать от 8 до 25% общего времени рабо- ты над проектом. Это согласуется с данными многих авторов (рис. 22-1).
Рис. 22-1. По мере увеличения объема проекта тестирование,
выполняемое разработчиками, отнимает все меньшую часть общего времени
разработки. О влиянии размера программы на конструирование см. главу 27
Другой важный вопрос: что делать с результатами тестирования, выполняемого разработчиками? Прежде всего вы можете сразу использовать эти результаты для оценки надежности разрабатываемой системы. Даже если вы не исправляете де- фекты, обнаруженные при тестировании, оно характеризует надежность ПО. Кроме того, результаты тестирования позволяют определить необходимые исправления.
Наконец, со временем регистрация дефектов, обнаруженных при тестировании,
помогает определить наиболее частые типы ошибок. Вы можете использовать эту информацию для выбора и проведения подходящих обучающих курсов, при под- готовке будущих технических обзоров и разработке будущих тестов.
Тестирование во время конструирования
В большом мире тестирования тему этой главы — тестирование методом белого
(или прозрачного) ящика — иногда игнорируют. Как правило, проектировать
494
ЧАСТЬ V Усовершенствование кода классы следует так, чтобы они казались черными ящиками: пользователь класса должен обращаться к нему через интерфейс, не зная о деталях внутреннего уст- ройства класса. Однако при тестировании класса с ним выгодно обращаться как с прозрачным ящиком, анализируя внутренний исходный код, а также входные и выходные данные класса. Зная, что происходит внутри ящика, вы можете проте- стировать класс более тщательно. Конечно, при тестировании класса вы будете рассматривать его код под тем же углом зрения, что и при написании, поэтому тестирование методом черного ящика также имеет достоинства.
Во время конструирования вы обычно пишете метод или класс, проверяете его в уме, после чего выполняете его обзор или тестирование. Какой бы ни была ваша стратегия интеграционного тестирования или тестирования системы, вы долж- ны тщательно тестировать каждый блок до его объединения с другими блоками.
Если вы пишете несколько методов, тестируйте их по одному за раз. На самом деле так их тестировать не легче — зато гораздо легче отлаживать. Если вы объедини- те несколько непротестированных методов и получите ошибку, вы не сможете определить, какой из методов в ней повинен. Если же вы добавляете в набор про- тестированных методов по одному методу за раз, при возникновении ошибки вы будете знать, что она содержится в добавленном методе или обусловлена взаимо- действием старых методов с новым. Это облегчит отладку.
Методики совместного конструирования имеют много достоинств, не характер- ных для тестирования. Однако частично это объясняется тем, что тестирование часто выполняют не так хорошо, как было бы можно. Разработчик может выпол- нить сотни тестов и все же достигнуть лишь частичного покрытия кода тестами.
Чувство хорошего покрытия кода тестами не означает, что покрытие на самом деле адекватно. Понимание базовых концепций тестирования может повысить его эффективность.
22.2. Рекомендуемый подход к тестированию,
выполняемому разработчиками
Систематичный подход к тестированию, выполняемому разработчиками, позво- ляет находить максимальное число дефектов всех типов при минимуме усилий.
Поэтому соблюдайте все правила, указанные в следующем списке.
쐽
Тестируйте программу на предмет реализации каждого существенного требо- вания. Планируйте тесты для этого этапа на стадии выработки требований или как можно раньше — лучше всего до написания тестируемого блока. Подумайте о тестах, которые позволили бы выявить распространенные пробелы в требо- ваниях. Уровень безопасности, хранение данных, процедура установки и на- дежность системы — все эти области тестирования часто упускаются на этапе выработки требований.
쐽
Тестируйте программу на предмет реализации каждого значимого аспекта проектирования. Планируйте тесты для этого этапа на стадии проектирования или как можно раньше — до начала детального кодирования метода или клас- са, подлежащего тестированию.
1 ... 56 57 58 59 60 61 62 63 ... 104
ГЛАВА 22 Тестирование, выполняемое разработчиками
495
쐽
Используя «базисное тестирование», дополните тесты требований и проекта детальными тестами. Разработайте тесты, основанные на потоках данных, а затем создайте остальные тесты, нужные для тщательного тестирования кода.
Как минимум вы должны протестировать каждую строку кода. О базисном те- стировании и тестировании, основанном на потоках данных, см. ниже.
쐽
Используйте контрольный список ошибок, созданный вами для текущего про- екта или в предыдущих проектах.
Проектируйте тесты вместе с системой. Это помогает избегать ошибок в требо- ваниях и проекте, которые обычно дороже ошибок кодирования. Выполняйте тестирование и ищите дефекты как можно раньше, потому что в этом случае ис- правление дефектов будет дешевле.
Когда создавать тесты?
Разработчики иногда интересуются, когда лучше создавать тесты: до написания кода или после? (Beck, 2003) Из графика повышения стоимости дефектов (рис. 3-1) сле- дует, что предварительное написание тестов позволяет свести к минимуму интервал времени между моментами внесения дефекта и его обнаружения/устранения. Есть и другие мотивы предварительного написания тестов:
쐽
создание тестов до написания кода требует тех же усилий: вы просто изменя- ете порядок выполнения этих двух этапов;
쐽
если вы пишете сначала тесты, вы найдете дефекты раньше, да и исправить их легче;
쐽
предварительное написание тестов заставляет хоть немного задумываться о требованиях и проекте до написания кода, что способствует улучшению кода;
쐽
предварительное написание тестов позволяет найти проблемы в требованиях до написания кода, потому что трудно создать тест для плохого требования;
쐽
если вы сохраняете свои тесты, что следует делать всегда, вы можете выпол- нить тестирование и после написания кода.
По-моему, программирование с изначальными тестами — одна из самых эффек- тивных методик разработки ПО, возникших в последнее десятилетие. Но это не панацея, потому что такой подход тоже страдает от общих ограничений тести- рования, выполняемого разработчиками.
Ограничения тестирования, выполняемого разработчиками