Тестирование-книга. Ю. Н. Артеменко Научный редактор
Скачать 6.27 Mb.
|
Часть 1. Основы Первые пять глав посвящены основам предметной области. И хотя прежде всего они предназначены для новичков, прочитать их следует всем. Новичку Чтобы книга принесла вам как можно больше пользы (и удовольствия), лучше всего поступить так. Внимательно прочтите главы 1, 2, 4, 5 и про смотрите главу 3. Затем, если возможно, в течение нескольких недель зай митесь практическим тестированием, выявите несколько ошибок и добейтесь их исправления, и только после этого продолжите чтение. Преподавателю Если у ваших студентов нет практического опыта, перед переходом к главе 6 стоит организовать практические занятия (часов на 10—20). Для занятий можно взять какой-нибудь коммерческий продукт — в них всегда Структура книги 15 множество ошибок. На этом этапе занятий не стоит добиваться аналити ческого подхода. Пусть студенты просто выявят ошибки и составят о них письменные отчеты. В конце занятий подведите итоги сделанному и ука жите студентам на пропущенные тесты и слабые места в их работе. Часть 2. Приемы и технологии тестирования Главы 6—12 содержат разнообразный практический материал. Их мож но читать независимо и в любом порядке (только перед главой 6 нужно обязательно прочитать главу 5). Информация этой части полезна специа листу по тестированию любого уровня. Вторая часть несколько сложнее первой и предназначена прежде всего для читателей, которые составляют планы работ и руководят небольшими группами тестировщиков или же обучают будущих специалистов. Однако с этим материалом смогут спра виться и новички, проработавшие главы 1—5. Новичку В главе 6 рассказывается о том, как должна быть организована работа групп разработчиков и маркетинга с предоставленными тестировщиками отчетами об ошибках, а также о том, как упорядочить выявление и устра нение ошибок с помощью базы данных. Эта глава будет особенно интерес на тем из читателей, кто на собственном опыте прочувствовал, каково выполнить огромную работу по выявлению и протоколированию ошибок, а потом обнаружить, что часть этой работы просто пропала зря из-за пло хой организации: отчеты потерялись, были проигнорированы или неверно поняты. Те, у кого есть подобный опыт, лучше других поймут, насколько важно все, что может улучшить организацию составления отчетов и рабо ты с ними. Если же шестая глава покажется вам скучной, просто просмот рите несколько ее начальных разделов до раздела "Организация базы данных". Глава 8, посвященная тестированию печати, содержит по этому вопросу очень подробные сведения. Если тестируемая программа много печатает, в команде тестировщиков обязательно должен быть специалист, который очень хорошо разбирается в этом вопросе. Если глава кажется вам черес чур подробной или тестируемые вами программы мало печатают, постарай тесь понять суть описанной стратегии тестирования. Разберитесь, в чем состоит различие между ошибками, независимыми от устройств, ошибка ми принтера (или модема, терминала, видеоплаты и т.п.), ошибками драй вера и аппаратными ошибками. Если вы поймете, почему необходимо выявлять ошибки всех этих типов, причем именно в указанном порядке, тогда вы поймете суть концепции тестирования печати. 16 Тестирование программного обеспечения Преподавателю Проводя интервью для приема на работу новых сотрудников, мы все гда очень рады, если кандидат может представить примеры своей работы (планы тестирования или отчеты). Обычно такие материалы являются ком мерческой тайной, и в течение ряда лет после окончания работ показывать их никому нельзя. Вот несколько проектов, которые могут быть выполне ны студентами и материалы которых они смогут сохранить на будущее. • Создание схемы условий для данных (см. главы 7 и 12) сложных и перегруженных форм ввода. Для тестирования можно взять одну из недорогих коммерческих программ, предназначенных для работы с какой-либо базой данных — например, программу, выписывающую чеки, адресную книгу или менеджер контактов. Сколько нужно те стов, чтобы проверить каждое из требований к вводимым данным в отдельности? Сколько тестов понадобиться для проверки всевозмож ных комбинаций этих условий? Определите каждую комбинацию, которую необходимо проверить. Напишите короткую программу, использующую генератор случайных чисел (глава 7), для выполне ния проверки работы всех комбинаций условий. Будет ли такой подход лучше тестирования вручную? • Студент, понимающий, как программное обеспечение взаимодей ствует с аппаратной частью системы, может самостоятельно напи сать версию главы 8 для работы с модемом, мышью, видеоплатой или любым другим устройством. Пусть он включит в нее примеры тестов для специфических типов коммерческих программ. • Протестируйте коммерческие программы на соответствие прилагаю щимся к ним руководствам и другой документации (глава 10). От четом может служить само руководство с пометками плюс самостоятельные отчеты о тех несоответствиях между программой и документацией, которые являются результатами ошибок в програм ме. • Протестируйте какую-нибудь коммерческую программу с использо- ванием средств автоматизации тестирования (глава 11). Сколько времени понадобится, чтобы подготовить тесты различных типов? Сколько времени займет эта же работа вручную? Насколько может измениться программа, чтобы разработанные тесты все еще были к ней применимы? И исходя из ответов на эти вопросы, как намере ны студенты использовать подобные средства — при каких обстоя тельствах и для каких типов тестов? Структура книги 17 Часть 3. Управление проектами и группами Материал последних глав (13—14) предназначен прежде всего для спе циалистов, руководящих тестированием проекта. От рассмотрения деталей мы переходим к более глобальному анализу работ — на уровне плана те стирования (глава 12) и проекта в целом (глава 13). Глава 15 посвящена эф фективному управлению работой группы тестирования. Соглашения Как и многие другие, эта книга имеет иерархическую структуру. Мы постарались облегчить читателю отслеживание этой иерархии, выделив заголовки разных уровней соответствующими шрифтами. Это главный заголовок Это заголовок второго уровня Это заголовок третьего уровня ЭТО заголовок четвертого уровня Кроме того, в книге используются следующие способы выделения тек ста: Полужирным шрифтом набраны фрагменты текста, которые долж ны выделяться из контекста. Например, это может быть текст, ко торый нужно набрать с клавиатуры, текст, отображаемый на экране компьютера, фрагмент распечатанного отчета, имя поля базы дан ных или имя переменной. Курсивом выделены впервые встретившиеся в книге важные терми ны. Значение такого термина объясняется в том же разделе. Названия клавиш заключены в угловые скобки, например, Ссылаясь на другой раздел книги, мы разделяем заголовки включа ющих его разделов и подразделов двоеточиями. Выглядит ссылка так: См. в главе 12 раздел "Главный заголовок: Заголовок второго уров ня: Заголовок третьего уровня". 18 Тестирование программного обеспечения Благодарности Работа над этой книгой была начата в 1983 году, а в 1988 году в изда тельстве Канера (Kaner) вышло ее первое издание. За годы работы нам помогали многие люди, читавшие рукопись и первое издание книги и высказавшие множество полезных замечаний. Вот те, кому мы хотим выразить особую благодарность (в алфавитном порядке): профессор Элейн Андерсен (Elaine Andersson), д-р Борис Бейзер (Boris Beizer), Джим Брукс (Jim Brooks), Рэнди Делюччи (Randy Delucchi), Мэл Дауэри (Mel Doweary), Дэвид Фамер (David Farmer), профессор Ларри Джонс (Larry Jones), Шарон Гафнер (Sharon Hafner), Махмуд Кан (Mahmood Kahn), Джинни Канер (Ginny Kaner), д-р Сэм Канер (Sam Kaner), Джон Лавель (John Lavelle), д-р Лэрри Мэлкас (Larry Malkus), Тэд Мацумара (Ted Matsumara), д-р Дон Максвелл (Don Maxwell), Брюс Мил лер (Bruce Miller), Рэйчел Миллер (Rachel Miller), Питер Морзе (Peter Morse), Джейн Степак (Jane Stepak), и Эммануель Эрен (Emmanuel Uren). Конечно, за все оставшиеся в книге ошибки отвечают только ее авто ры. Часть I Основы Глава 1. Пример серии тестов Глава 2. Желаемое и действительное в жизни тестировщика Глава 3. Типы тестов и их роль в процессе разработки программного обеспечения Глава 4. Программные ошибки Глава 5. Документирование и анализ ошибок Глава 1 Пример серии тестов Назначение этой главы Процесс тестирования программного обеспечения можно отчасти назвать интуитивным, но в то же время в основе его лежит вполне системати зированный подход. Хорошо протестировать программу означает нечто гораздо более серьезное, чем просто "погонять" ее несколько минут, чтобы убедиться, что она работает. Эффективное тестирование требу ет тщательного анализа и строгого системного подхода. Эта глава является своеобразным введением, цель которого — на про стом примере продемонстрировать подход к тестированию программ, применяемый опытными специалистами этого дела. Для примера мы выб рали маленькую незамысловатую программку с несколькими ошибками. Первый цикл тестирования Вместе с программой, которую следует протестировать, вы получили та кое описание. Назначение программы — сложить два введенных вами числа. В каж дом из чисел должна быть одна или две цифры. Программа выполняет эхо-отображение вводимых чисел, а затем выводит их сумму. Ввод каж- дого числа завершается нажатием клавиши ма с помощью команды ADDER. Шаг 1. Начнем с простого и наиболее очевидного теста Для начала с программой нужно познакомиться и посмотреть, доста точно ли она стабильна, чтобы ее можно было тестировать. В программах, предоставленных для первого формального тестирования, часто сразу же происходит сбой. Не стоит тратить на них много времени. Глава 1: Пример серии шестов 21 В первом тесте складываются числа 2 и 3. Последовательность дей ствий и результат приведены на рис. 1.1. А на рис. 1.2 видно, как выгля дит экран по окончании теста. Курсор (мигающий символ подчеркивания позади знака вопроса вни зу экрана) указывает, где будет отображаться следующее вводимое число. Отчет о проблемах, выявленных первым тестом Программа работает — она приняла числа 2 и 3 и вернула 5. Но про блемы все же есть. Для их описания составляется отчет, форма которого приведена на рис. 1.3. 1. Ошибка проектирования. Нет никаких указаний на то, с какой про граммой вы работаете. Откуда вам знать, что именно с той, кото рая нужна? 2. Ошибка проектирования. На экране нет никаких инструкций. Откуда вам знать, что нужно делать? Что, если вы вводите недопусти мые числа? Отобразить инструк цию на экране не трудно, и она всегда будет перед глазами, в то время как печатная документация может потеряться. 3. Ошибка проектирования. Как оста новить программу? Эта инструк ция тоже должна быть на экране. 4. Ошибка кодирования. Сумма (чис ло 5) выведена в стороне от сла гаемых. Глава 1: Пример серии тестов 23 Обязательно представляйте отдельный "Отчет о проблеме" по каждой ошибке. Описание всех четырех ошибок можно было бы поместить в один отчет, но лучше этого не делать. Ошибки могут исправляться в разное время, и сведения о тех из них, которые остались неисправленными, могут просто потеряться. Если программист захочет их сгруппировать, он сам рассортирует отчеты. Чтобы привлечь внимание к взаимосвязанным проблемам, просто поместите в отчеты соответствующие ссылки. Шаг 2. Составим заметки о том, что еще должно быть протестировано Выполнив первые, и самые очевидные тесты, следует подумать о том, что еще следует протестировать. Свои соображения нужно записать: одни из записей примут форму заметок, другие же могут представлять собой достаточно строго формализованные описания серий тестов. Такие доку ментированные группы тестов в дальнейшем могут послужить для провер ки следующих версий программы. Примером может быть серия тестов, представленная на рис. 1.4. 24 Часть I: Основы Эти тесты охватывают все допустимые входные данные программы — пары чисел, которые ей полагается складывать правильно. В первом тесте вы ввели два числа и проверили результат. Фактичес ки все оставшиеся 39600 тестов точно такие же. Выполнять их все было бы безумием. На рис. 1.4 для тестирования программы предлагается во семь примеров. Почему только восемь и почему именно таких? Прежде всего, тесты были подобраны так, чтобы каждая цифра встречалась в них хотя бы один раз. Кроме того, мы подобрали по одной комбинации чи сел на каждую из вероятных проблем. А чтобы определить, на каких дан ных вероятнее всего возникнут проблемы, эффективнее всего проверить граничные условия. Количество возможных тестов (39601) вычисляется так. В допустимом диапазоне от -99 до 99 всего 199 чисел. Любое из них может стоять на первом месте и любое — на втором. Всего получается 199 2 = 39601 пар чисел. Заметьте, что такое количество тестов выходит даже без учета любых чуть более сложных действий пользователя, как, например, нажа тия клавиши Задача определения количества возможных тестов относится к области математики, именуемой комбинаторным анализом. Обычно задача эта не сложная — необходимые формулы можно найти в любом учебнике по теории вероятности или комбинаторике. Если вы проверяете комбинацию 2 + 3, а затем 3 + 4, ваши тесты хотя и не в точности одинаковы, но очень близки. Оба они проверяют, как ре агирует программа на пару однозначных положительных чисел. И если программа пройдет первый тест, наиболее вероятно, что она пройдет и второй. Поэтому из огромного количества возможных тестов нужно выби рать только наиболее важные. Из двух тестов, от которых ожидается один и тот же результат, проводите только один. Если от двух тестов ожидается получить один и тот же результат, значит, они принадлежат к одному классу. В нашем случае 81 тест отно сится к классу "пара однозначных положительных чисел". Как только удается выделить класс, т.е. группу однотипных тестов, можно провести несколько из них и проигнорировать остальные. Для отбора проводимых тестов есть важное правило. Для выполнения всегда выбирайте из класса те тесты, на которых вероятнее всего ожидается сбой программы. Глава 1: Пример серии тестов 25 Лучше всего подходят для тестирования примеры, лежащие на грани це представленного классом диапазона значений. Именно на граничных значениях программы сбоят чаще всего. Например, если программа пред назначена для сложения двузначных чисел, одним из граничных значе ний, которые она должна правильно обрабатывать, является число 99. Классом можно назвать группу значений, которые программа обраба тывает одним и тем же способом. А граничными значениями класса явля ются те входные данные, на которых программа меняет свое поведение. Однако граничные значения могут быть там, где вы их совсем не ждете, а там, где им положено быть, их в действительности может и не оказаться. Не всегда программа меняет свое поведение именно там, где предполагает программист, и именно в этом причина большинства оши бок. При программировании граничных условий случайная ошибка очень вероятна, поэтому такие точки следует проверять наиболее тщательно. Волшебной формулы для объединения тестов в группы и определения граничных условий не существует. Это умение приходит только с опы том. Прочитав программный код, можно найти в нем то, чего при исполь зовании программы вы не сможете даже предположить. Однако проверять те критические точки, которые можно определить по листингу, — это прежде всего работа программиста. А ваша задача — проанализировать программу с другой точки зрения, чтобы выявить те критические точки, которые программист пропустил. Поэтому классы возможных тестов вам следует выделять, исходя прежде всего из внешнего поведения програм мы. В результате набор тестов будет отличаться от того, который можно составить по листингу программы, — именно в этом суть вашей задачи. Напоследок упомяну еще об одном важном моменте. Границу значе ний обязательно нужно протестировать с двух сторон. Программисты часто убеждаются, что критический фрагмент кода работает на одном из значений и забывают это сделать на втором. Здесь они пропускают ошиб ки, которые вы пропустить не должны. Шаг 3. Проверим допустимые значения и посмотрим, что происходит Серия тестов, приведенных на рис. 1.4, охватывает только допустимые значения входных данных программы. На следующем этапе тестирования можно создать такую же серию тестов для недопустимых значений. Еще одна серия тестов может быть предназначена для проверки редактирова ния чисел: вы вводите значение, затем изменяете его и только после это- го нажимаете 26 Часть I: Основы Программу тестируют потому, что она может не работать. Можно убить уйму времени на разнообразные тесты, подсказанные ва шей фантазией, а затем обнаружить, что программа не может сложить 2 и 3. Вот результаты теста нашей программы-примера. • Положительные числа и 0 обрабатываются прекрасно. • Не работает ни один тест с отрицательными числами. После вво да второй цифры компьютер просто "зависает". (Он игнорирует клавиатурный ввод, и его приходится перезапускать.) Вы попробо вали сложить 9 и -9, чтобы посмотреть, не примет ли программа однозначные отрицательные числа, но после нажатия клавиши рицательных чисел. Шаг 4. Немного тестирования в режиме "свободного полета" Когда серии подготовленных тестов полностью выполнены, формаль ное тестирование можно считать завершенным. Однако это не значит, что нужно немедленно прекращать работу до следующего этапа. Тестирование можно продолжить. Тесты, которые вы будете проводить и выполнять с этого момента, не нужно тщательно готовить или объяснять кому-то их назначение. Здесь в дело должна вступить ваша интуиция. Пробуйте все, что придет вам в голову, даже если сотрудникам кажется, что подобные тесты уже были проведены. В нашем примере вы быстро достигли точки, в которой формальное те стирование переходит в неформальное, поскольку сбой программы не за ставил себя ждать. Вероятно, в ней есть какая-то фундаментальная ошибка. Если это так, проект программы следует пересмотреть. Разраба тывать новые тесты пока нет никакого смысла, поскольку к новой версии они могут просто не подойти. Поэтому, не тратя времени на планирова ние, можно провести несколько чисто исследовательских экспериментов — все, что придет в голову. На рис. 1.5 перечислены тесты, которые провели бы мы, их возможные результаты и наши замечания. Всегда записывайте, что вы делаете и что происходит во время исследовательских тестов. Как видно из рис. 1.5, программа никуда не годится: она "зависает" при малейшей провокации. Вы больше времени тратите на перезапуски компьютера, чем на тестирование. Столкнувшись с очередной проблемой, вы составляете о ней отчет. О сданных отчетах лучше написать для себя итоговые заметки. На этом те стирование первой версии программы можно считать завершенным. Шаг 5. Подведем итоги тому, что мы узнали о программе и ее недостатках Эта последняя работа — только для вас. Она не всегда необходима, но часто оказывается очень полезной. До этого времени вы все время были сконцентрированы на конкретных деталях — анализировали допустимые данные, продумывали граничные условия и составляли тестовые примеры. В будущем вы больше времени будете тратить на выполнение уже подготовленных тестов, чем на приду мывание новых. Сейчас же самое время мысленно отступить немного назад и окинуть взглядом программу в целом, увидеть ее недостатки и продумать стратегию будущего тестирования. 28 Часть I: Основы Результатом такого более глобального анализа может быть обнаруже ние пропущенных деталей — например, новых граничных условий. Очень полезно для начала записать свои итоговые впечатления о про грамме. Вот они. • У программы очень ограниченный интерфейс. • Программа не работает с отрицательными числами. Наибольшая сумма, которую она может вычислить, — 198, а наименьшая — 0. • Третий вводимый символ (например, третью цифру в числе 100) программа интерпретирует как нажатие < Enter>. • Пока вы не нажмете принимаются как допустимые. • Программа не проверяет, действительно ли вы ввели число, преж де чем нажали пользует последнее число, введенное ранее. Если предположить, что программист не является безнадежно неком петентным, то для таких непривлекательных результатов должна быть причина. Скорее всего, она состоит в том, что программист пытался сде лать программу как можно меньшей по размеру или как можно более быстрой. Код обработки ошибок занимает память. Это же касается заголовков, сообщений об ошибках и инструкций. Если программа должна поместить ся в очень маленьком фрагменте памяти, для всего этого места нет. По добным же образом обстоит дело и со временем: оно требуется и на проверку допустимости вводимых символов, и на проверку того, что тре тьей нажатой клавишей действительно является редного задания. По одному только перечню недостатков программы трудно судить, действительно ли они вызваны жесткими требованиями к ее скорости или размерам. И если да, нет ли возможности исправить хотя бы часть из них, не выходя за пределы этих ограничений. Чтобы все это выяснить, нужно поговорить с программистом. Предположим, что главной целью программиста является экономия памяти. Как он ее достигает? Большинство способов очевидно: никакого кода обработки ошибок, никаких сообщений о них, никаких инструкций на экране, никакого кода проверки третьего символа. Может быть, есть и другие способы? Без сомнения. Минимизировать требования к памяти можно за счет эффективного хранения данных. В этой программе данны ми являются вводимые символы и сумма. Глава 1: Пример серии тестов 29 Хранение суммы Допустимыми могли бы быть суммы от -198 до 198. Но программа ра ботает только с положительными числами, поэтому в ней возможны сум мы от 0 до 198. Если хранить только положительные числа, то хватит и одного байта (8 битов). Это стандартная и очень удобная единица хранения данных, вмещающая положительные числа от 0 до 255. Если программист хотел выбрать для хранения суммы наименьший возможный размер переменной и при этом не считал необходимой обработку отрицательных чисел, байт был идеальным решением. Вот только что будет, если программа изменится и должна будет об рабатывать отрицательные числа тоже? Собственно говоря, байт можно использовать для хранения и положительных, и отрицательных чисел, нужно только один из битов выделить для хранения знака. Тогда в одном байте можно хранить числа от -127 до 127. На числах, превышающих 127, программа будет сбоить. Подобные сбои обычно выражаются в том, что числа, которые боль ше чем 127, интерпретируются как отрицательные. Скорее всего, то же будет и с нашей программой. В следующей серии тестов следует обратить внимание на большие суммы — граничными будут значения 127 и 128. Серия тестов на рис. 1.4 уже включает большую сумму (99 + 99), поэто му новые тесты понадобятся только в случае, если этот программа прой дет правильно. Рядом с этим примером стоит приписать замечание, чтобы отследить неверный результат. Этот пример граничного условия интересен тем, что он зависит от спо соба хранения данных, выбранного программистом или определенного языком программирования. Обычно типы данных определяются в начале программы или в отдельном файле. Просматривая ту часть кода, в кото рой выполняется сложение, можно не увидеть ничего подозрительного. Программа получает два числа, складывает их, записывает куда-то резуль тат — все выглядит безупречно. Вот только случается, что сумма не по мещается туда, куда ее записывают. И подобные ошибки пропустить очень легко, ведь логика той части программы, которая выполняет сложе ние, проста и правильна. Хранение входных данных Разобравшись с хранением суммы, перейдем к анализу символов, ко торые пользователь вводит с клавиатуры. Сейчас вы увидите, как знание программы изнутри может помочь в со ставлении следующей серии тестов. Речь пойдет о скрытых граничных точ ках — тех, которые не видны пользователю программы и выявляются только при чтении исходного кода. В нашем примере такие тесты можно 30 Часть I: Основы составить и без чтения кода — на основании знаний о ASCII-кодировке символов. Но в общем случае, чем больше вы знаете о про граммировании, тем больше граничных точек сможете выявить. Следующий пример новичкам в тестирова нии и тем, у кого нет программистского опы та, будет непонятен. Поэтому его смело можно пропустить и сразу перейти к следующему разделу. Клавиатурный ввод обычно принимается и обрабатывается специальной системной про граммой. Эта программа назначает каждой клавише числовой код, который при нажатии клавиши передается прикладной программе. Одной из классических кодировок является ASCII. Коды цифр в этой таблице приведены на рис. 1.6. Когда вы нажимаете клавишу, программист проверяет ее ASCII-код, чтобы выяснить, была ли введена цифра. Этот фрагмент программы выглядит примерно так. IF АSСII_КОД_ВВЕДЕННОГО_СИМВОЛА меньше 48 (48 — это ASCII-код для 0) THEN отвергнуть символ как недопустимый ELSE IF АSСII_КОД_ВВЕДЕННОГО_СИМВОЛА больше 57 (57 — это ASCII-код для 9) THEN отвергнуть символ как недопустимый ELSE это цифра, принять ее. Посмотрим теперь, из-за чего этот код может сработать неправильно. Вот шесть наиболее распространенных ошибок программистов. • Если вместо оператора меньше программист поставит оператор мень ше или равно, программа отвергнет 0 как недопустимый символ. Чтобы найти эту ошибку, нужно проверить, как программа рабо тает с нулем — цифрой с наименьшим кодом ASCII (48). • Если вместо меньше 48 программист напишет меньше 47, програм ма примет символ /, решив, что это цифра. Чтобы найти эту ошибку, нужно проверить, как программа работа ет с символом / — символом, код которого на единицу меньше кода нуля. Глава 1: Пример серии тестов 31 • Если программист допустит опечатку и вместо меньше 48 напишет меньше 38, программа примет не только символ /, но и девять дру гих нецифровых символов с кодами от 38 до 47. Для выявления этой ошибки можно проверить любой символ из этого диапазона, граничным значением которого будет код 47. • Теперь посмотрим на самую большую цифру — 9 (ASCII-код 57). При работе с ней, вероятнее всего, может встретиться ошибка больше или равен 57 вместо равен 57. Если ввести 9, программа от вергнет этот символ как нецифровой. Такой код неверно работает с одной-единственной цифрой — ее и нужно проверить. • Программист может захотеть записать второе условие иначе, как больше или равен 58, но по ошибке написать больше 58. Тогда про грамма примет за цифру двоеточие. • Еще одной опечаткой программиста может быть 75 вместо 57, тогда программа будет принимать за цифры все символы с кодами от 48 до 75. Эту ошибку можно обнаружить, проверив любой символ из указанного диапазона, но символа с граничным значением кода (двоеточия) будет вполне достаточно. ДЛЯ обнаружения любой ошибки, которую программист может допустить при анализе цифровых данных, достаточно проверки всего четырех граничных символов: /, 0, 9, и :. Из приведенных в таблице на рис. 1.6 символов два последних мы ис пользовали, чтобы выяснить, как программа реагирует на нецифровые данные. Тест сработал, а программа — нет. Но как быть с шестью пере численными типами ошибок? Одной проверкой буквы А их не выявить. А буква b вообще ничем не поможет. Так что проверять нужно граничные символы (/, 0, 9, и :), поскольку, повторюсь, самыми эффективными яв ляются тесты именно граничных значений. Первый цикл тестирования. Итоги Вы начали с простейшего из возможных тестов. Поскольку программа его прошла, вы разработали серию формальных тестов, чтобы проверить, как она работает с допустимыми данными. Эти тесты вы будете исполь зовать и дальше. Поскольку часть проверок программа не прошла, на пла нирование дальнейших серий тестов вы решили времени не тратить. Вместо этого вы провели несколько неформальных экспериментов и выяснили, что 32 Часть I. Основы программа вообще очень нестабильна. Вы записали несколько замечаний, к которым обратитесь при тестировании следующей версии программы. Если бы программа успешно прошла первую серию тестов, вы бы раз работали вторую, более обстоятельную. Если бы программа снова показа ла себя надежной, вы бы продолжили ее тестирование, пока не исчерпались бы идеи или отведенное время. Напоследок вы провели бы несколько бег лых тестов, не входивших в ранее разработанные серии, и записали заме чания на будущее. Завершив тестирование и всю бумажную работу, стоит потратить еще немного времени, чтобы обдумать результаты. Вы выполнили самое оче видное, но это еще только начало. У вас нет пока конкретного плана. Вы просто делали то, что первым приходило в голову. По ходу работы вы оп ределили две линии атаки. Теперь же нужно выделить время на обдумыва ние. Это очень важно, даже если сроки сильно поджимают. Второй цикл тестирования Вы поговорили с программистом, и он сказал, что скорость работы про граммы исключительно важна, а вот объем кода не имеет никакого значения. Резолюции программиста на ваших отчетах представлены на рис. 1.7. Глава 1: Пример серии тестов 33 Шаг 1. Прежде чем приступить к тестированию, внимательно прочтите резолюции программиста на ваших отчетах - вы узнаете, что нужно делать, а чего не нужно Как видите, хорошо, что вы не разрабатывали тестов для проверки кода обработки ошибок: этого кода нет и не будет. Более того, хотя програм ма и будет теперь обрабатывать отрицательные числа, она будет обраба тывать их не все, а только до -9. Числа от -10 до 199 длиной в три символа она по-прежнему не обра батывает, интерпретируя третий символ как нажатие клавиши Обратившись к разработанной ранее серии тестов на рис. 1.4, вы видите, что тесты с числами -99, -78 и -14 запускать не придется. Вместо -78 и -14 возьмите пару однозначных отрицательных чисел. Очень часто программист просит протестировать остальную часть про граммы, в то время как он занимается исправлением уже найденных оши бок — и это разумно. Некоторые из запланированных тестов нет смысла проводить до исправления ошибки, с другими же вполне можно порабо тать. Если ждать, пока можно будет провести "лучшие" из тестов, мож но оставить без внимания целые области программы, на которые потом уже не хватит времени. В нашем примере можно протестировать числа между -1 и -9 — так вы хоть и не полностью, но проверите, как работа ет сложение отрицательных чисел, вместо того чтобы опустить эту про верку вообще. Из резолюций на ваших отчетах вы увидите, какие тесты больше про водить не нужно, а какие нужно заменить новыми. Станут ли резолюции программиста ключом к созданию новых серий тестов? Без сомнения. Шаг 2. Проанализируйте комментарии к ошибкам, которые не будут исправлены. Возможно, следует провести дополнительное тестирование В нашей программе хуже всего обстоит дело с обработкой ошибок. Программист не собирается исправлять ситуацию. Как же быть? Чтобы добиться исправления ошибки, нужно продемонстрировать ситуацию, в которой ее появление абсолютно недопустимо. Чтобы придумать самые показательные примеры недопустимого пове дения программы, постарайтесь выявить суть ситуации. 34 Часть I: Основы В нашем случае программа "зависает", когда вы нажимаете определен ные клавиши. Так она ведет себя с буквами, управляющими и функцио нальными клавишами. Фактически программа "зависает" при вводе любого недопустимого (нецифрового) символа. Программист говорит, что таких символов вы вводить не должны. С вашей же точки зрения, программа должна вести себя вежливо и не заставлять вас перезапускать компьютер каждый раз, когда вы сделаете что-то не так. Прекрасно. Теперь вернем ся назад. Программа некорректно ведет себя в ответ на нажатие некото рых клавиш. Программист считает, что это не страшно, поскольку никто и не ждет, что программа примет эти клавиши. А что, если программа "зависнет" в ответ на ввод символов, которые, по мнению пользователя, она должна принять? Если найти достаточно таких символов, программисту придется написать код для их обработки, а заодно уж он может обработать и остальные символы. Подумаем, какие же клавиши люди могут нажимать при работе с арифметической программой. Здесь нужен мозговой штурм. Запишите все клавиши, которые человеку может прийти в голову нажать. Запишите, почему эти клавиши могут показаться уместными. Пусть вас не беспоко ит, согласится ли программист с вашими предположениями — позднее вы еще пересмотрите свой список и отберете из него самое существенное. На рис. 1.8 показан список, который получился у нас. Глава 1: Пример серии тестов 35 Некоторые из идей в нашем списке явно неудачны. Например, если сказать программисту, что программа не обрабатывает 4/3 + 2, он толь ко посмеется. Но для первой версии списка это не имеет значения. Преж де всего, важно ничего не пропустить. А что внести в отчет, вы решите чуть позже. Шаг 3. Просмотрите записи, которые вы сделали в прошлый раз, добавьте к ним новые замечание, и приступайте к тестированию Вам страшно хочется начать с того замечательного и очень сложного теста, который вы только что придумали, не так ли? Не торопитесь. Сна чала повторите старые и нудные тесты и убедитесь, что программа по-пре жнему может сложить 2 и 2 и не получить при этом 5. С вероятностью 1:2 программа не сработает или в ней возникнут новые неполадки. Поэтому обязательно протестируйте все сначала. Вы провели все "формальные" серии тестов (см. рис. 1.4), модифици ровав несколько примеров для проверки однозначных отрицательных чисел. Программа все их успешно прошла. По ходу дела вы заметили, что программа отображает подсказку "Для выхода нажмите Программист говорит, что программа должна работать быстро. Тогда все, на что тратится лишнее время, является ошибкой. Вы составили сле дующий отчет. 10. Ошибка проектирования. На вывод на экран подсказки "Для выхода нажмите скольку одной из задач разработки является создание очень быст рой программы, это ошибка. Почему бы просто не написать "Для выхода нажмите граммы" и никогда больше ничего не выводить в этой строчке? (И если это возможно, почему бы заодно не вывести также и заголо вок программы и короткие инструкции?) Среди ваших заметок есть напоминание проверить однобайтовые сум мы. Это диапазон значений от -127 до 127 или от 0 до 255. Поскольку двузначных отрицательных чисел задавать нельзя, -127 в допустимый диапазон не попадает. Однако сложение 99 и 99 дает правильный резуль тат, значит, все в порядке. Однако не расслабляйтесь. Некоторые из тестов обязательно выявят про- лемы, и чем тщательнее вы продумаете свои действия, тем больше обна ружите скрытых недостатков программы. 36 Часть I: Основы Если программист достаточно аккуратен, большая часть ваших тестов, включая и те, которые потребовали наибольшей изобретательности, не выявит ошибок. Последним вы намеревались протестировать блок обработки ошибок. Но вводить трехзначные числа пока нельзя — здесь есть ошибка, которая в это время как раз исправляется. Остался вопрос с недопустимыми кла вишами, такими как перечисленные на рис. 1.8: В ответ на нажатие любой из этих клавиш, за исключением знака "ми нус", программа "зависает". Вот какой "Отчет о проблеме" вы составля ете. 11. Ошибка кодирования. Проблема. В ответ на нажатие клавиш редактирования и других пред положительно допустимых клавиш программа "зависает". Подробное описание проблемы и как ее воспроизвести: Проблема с нециф ровыми клавишами гораздо более серьезна, чем следует из отчетов 7, 8 и 9. В соответствии с этими отчетами компьютер "зависал" при вводе сим волы, которых в арифметической программе никто вводить не станет. Дальнейшее тестирование показало, что к тому же результату приводит и нажатие таких естественных клавиш, как <Пробел>, которым многие пользуются, чтобы подровнять числа. Приво- дит к сбою программы и знак "плюс", а его многие просто рефлекторно! нажмут между складываемыми числами. (Вот простейший пример для! воспроизведения проблемы: введите А, затем нажмите Предлагаемое исправление. Проверять каждый вводимый символ. Недо пустимые символы игнорировать или выводить сообщение об ошибке. Глава 1. Пример серии тестов 37 Обратите внимание на то, с чего отчет начинается: вы утверждаете, что проблема серьезнее, чем это следует из предыдущих отчетов. Это дает про граммисту возможность сохранить лицо. Он может сказать, что не испра вил ошибку в прошлый раз потому, что не понял (вы ему не сказали), насколько она серьезна. Хороший тестировщик не тот, кто выявит больше всего ошибок, и не тот, кто заставит смутиться даже самого первоклассного программиста. Лучшим является тот, кто добьется исправления наибольшего количества ошибок. Что дальше? По мере дальнейшей разработки программы вы будете создавать новые серии формальных тестов и выполнять их снова и снова — для каждой версии программы, которая попадет вам в руки. Увидев, что ряд последо вательных версий программы успешно проходит одну из серий тестов, можно будет уменьшить их количество. Но в последнем цикле тестирова ния все тесты нужно снова выполнить в полном объеме. Когда работа над проектом приблизится к концу, придет время самых строгих и самых сложных тестов. К этому моменту вы уже будете знать программу во всех тонкостях, изучите все ее слабые места. И наряду с проведением этих последних тестов вы подумаете о том, чтобы снова поднять вопросы, которые по каким-то причинам решены не так, как следует на ваш взгляд. Это последняя возможность добиться ис правления ошибок, которые вы считаете серьезными. Вы тут выиграете далеко не каждое сражение, но вы и не ставите целью добиться исправ ления всех оставшихся ошибок. Более того, накануне завершения проек та попытки исправить как можно больше ошибок могут принести больше вреда, чем пользы. Всегда наступает момент, когда с некоторыми недостат ками приходится смириться. Ваша главная задача — добиться, чтобы те, кто отвечает за ход разработки, до конца понимали серьезность каждой описанной вами проблемы. 2 Глава Желаемое и действительное в жизни тестировщика Назначение этой главы При планировании работ по тестированию программного продукта из ог ромного количества возможных тестов вам приходится отбирать лишь малую, но зато реально выполнимую часть. И как бы тщательно вы ни выполнили эти отобранные тесты, все ошибки до единой вам все равно не найти. Даже если в программе действительно не останется ошибок, вы об этом никогда не узнаете: ведь этого нельзя ни доказать, ни проверить. Многие новички приступают к работе в полной уверенности, что: • могут полностью протестировать любую программу; • выполнив такое тестирование, могут не сомневаться, что программа работает правильно; • задача тестировщика заключается в том, чтобы гарантировать правиль ность работы программы путем проведения полного тестирования. Обнаружив, что их цель недостижима, многие тестировщики оказываются в полной растерянности. Как же тогда компания справляется со своей ра ботой? И какова их собственная роль? Но, расставшись с идеей о пол ном отсутствии ошибок, они со временем понимают, что можно просто хорошо протестировать программу и обучаются тому, как это сделать. Эта глава призвана разрушить несколько распространенных заблуждений и ответить на вопросы, которые рано или поздно задает себе каждый начинающий специалист по тестированию. • Какова цель тестирования? Глава 2: Желаемое и действительное в жизни тестировщика 39 • Чем хорошее тестирование отличается от плохого? • Сколько необходимо проводить тестов? • Как узнать, что сделано достаточно? Очевидно, что тестирование — это процесс поиска ошибок. Хороший набор тестов позволит найти больше ошибок, чем плохой, и ошибки эти будут более серьезными. Дальше в этой книге рассказывается о том, как выработать правильную стратегию тестирования (главным образом в главах 7, 8 и 13). Библиографическая справка В своей известной книге по философии науки, вышедшей в 1965 г., Карл Поупер (Karl Popper) утверждает, что правильный подход к проверке на учной теории заключается в поиске не подтверждающих, а опроверга ющих ее фактов — попытке доказать, что в ней есть ошибки. И чем более тщательное тестирование выдерживает выдвинутая теория, тем больше у нас уверенности в том, что она верна. Полностью протестировать программу невозможно Что означает полностью протестировать программу? Это означает, что по окончании тестирования в ней не должно остаться ни одной невыявлен- ной ошибки. Будут ли ошибки исправлены — это уже другой вопрос, но все имеющиеся проблемы должны быть известны и правильно поняты. Существует популярное убеждение, что программу можно полностью протестировать. • В некоторых учебниках для начинающих даже рассказывается, как это сделать: "Проверьте реакцию программы на все возможные ва рианты входных данных или все возможные последовательности вы полнения ее кода". Вскоре мы увидим, что ни того ни другого недостаточно для полного тестирования, и, как правило, выполнить эти рекомендации вообще невозможно. • В возможность проведения полного тестирования верят и многие менеджеры. Они требуют этого от своего персонала и по окончании работ уверяют друг друга, что задача выполнена. • Коммерческие представители некоторых компаний, специализирую щихся на тестировании программного обеспечения, обещают, что код заказчика будет полностью протестирован. • При продаже некоторых систем автоматизации тестирования вам обещают, что система сообщит, когда код будет протестирован пол ностью, а в ходе работы будет подсказывать, какие еще тесты позво лят выявить все оставшиеся ошибки. 40 Часть I: Основы • Многие продавцы программного обеспечения верят, что их товар полностью протестирован и не имеет ошибок, и горячо убеждают в этом покупателей. В миф о полном тестировании верят и некоторые несчастные тестиров- щики. Их гнетет вечное чувство вины, поскольку как бы тяжело они ни трудились, как бы тщательно ни планировали работу, сколько бы ни тра тили времени, сколько бы сотрудников и техники ни было задействовано в тестировании, все равно в программах остаются ошибки. И чтобы такому же заблуждению не поддались вы, ниже приводятся три причины, по которым полное тестирование не может быть выполнено никогда. • Количество всех возможных комбинаций входных данных слишком велико, чтобы его можно было проверить полностью. • Количество всех возможных последовательностей выполнения кода программы также слишком велико, чтобы его можно было проверить полностью. • Пользовательский интерфейс программы (включающий все возмож ные комбинации действий пользователя и его перемещений по про грамме) обычно слишком сложен для полного тестирования. Невозможно проверить реакцию программы на каждую комбинацию входных данных В предыдущей главе описывалась совсем простенькая программка, ко торая всего то и умела, что сложить два двузначных числа. И даже для нее объем возможных входных данных был огромным. Чтобы проверить эту программу полностью, нужно провести множество разнообразных тестов. Следует проверить все допустимые входные значения Даже эта простая программка должна правильно обрабатывать 39 601 различных пар чисел. Если бы она могла складывать четырехзначные числа, это количество выросло бы до 399 960 001. На практике же большинство программ работают с гораздо большими числами. Как все это протестиро вать? Следует проверить все недопустимые входные значения Вам следует поверить, как обрабатывает программа не только допусти мые входные данные, но и вообще все, что пользователь может ввести с клавиатуры. Это и буквы, и управляющие комбинации клавиш, и комби- Глава 2: Желаемое и действительное в жизни тестировщика 41 нации букв и цифр, и другие символы, как, например, знак вопроса. Вы должны знать, как программа отвечает на любые действия пользователя, что бы он ни ввел. Следует проверить все способы редактирования входных данных Если программа позволяет редактировать вводимые числа, нужно убе диться, что она это делает правильно. Проверьте, сможете ли вы изменить любой введенный символ. Протестируйте повторное редактирование: вве дите число, измените его, потом измените еще раз. Сколько раз нужно это сделать? Чтобы ответить на этот вопрос, приведем интересный пример. Оператора, работающего за интеллектуальным терминалом, отвлека ют. Он невнимателен. Нажимает числовую клавишу, затем Терминал отображает и стирает цифры на экране, но сохраняет всю последовательность кодов нажатых клавиш в буфере ввода. Наконец, пользователь вводит то, что хотел, и нажимает Это самая настоящая ошибка, и к тому же очень распространенная: и программисты, и тестировщики хорошо знают, как часто сбои программ бывают вызваны неожиданным событием. Можно очень долго тестировать блок редактирования входных данных и так и не быть до конца уверенным в его надежной работе. Следует проверить реакцию программы на ввод в каждый момент ее работы Нужно попробовать ввести данные, когда программа их совсем не ждет. Не дожидайтесь появления знака вопроса и мигающего курсора — вводи те числа, пока программа еще обрабатывает предьщущие данные, выводит на экран результат или отображает сообщение. Во многих системах в ответ на нажатие клавиш генерируется прерыва ние. Это прерывание означает, что компьютер должен приостановить ра боту и прочитать данные из входного потока. Обработав прерывание, компьютер продолжает выполнение программы. Чтобы убедиться в ее на дежности, нужно прерывать выполнение программы после каждой коман ды. О проблемах, связанных со временем и последовательностью событий, Рассказывается в главе 4 и приложении — они упоминаются под названи- ситуация гонок (race condition). В этом отношении уязвимы многие про- 42 Часть I: Основы граммы. Если важное для программы событие происходит в момент, ког да программа его не ждет, оно может быть просто не замечено или проиг норировано, неверно классифицировано, обработано неправильно или даже может вызвать сбой. Временная уязвимость — вопрос очень серьезный. И протестировать эту сторону работы программы не менее важно, чем другие. Что будет, если не проверить все возможные входные данные? Возможных тестов так много, что выполнить их все физически невоз можно. Проверьте все четыре типа ввода (допустимый, недопустимый, с редактированием и несвоевременный). Тщательно подберите тестируемые данные. Но помните, что, если хоть одно значение пропущено, тестирова ние останется неполным. Если вы убеждены, что можете полностью протестировать программу, не проверив ее реакцию на каждую возможную комбинацию входных условий, — прекрасно. Пришлите нам список предлагаемых вами тестов, и мы напишем программу, которая пройдет их все и продемонстрирует эффектный сбой в пропущенной вами ситуации. Если мы сможем сделать это намеренно, то, без сомнения, подобная ошибка может быть допущена программистом и случайно. Вот два примера сбоев в ситуациях, которые можно расценить как слишком сложные или маловероятные, чтобы их тестировать. • Одна программа управления базами данных разрушала файлы дан ных, размер которых был в точности кратным 512 байтам. Другая не могла работать с файлами, размер которых равнялся 16 384 байтам или был кратен этому числу, даже если она сама их создавала. • Один текстовый процессор сбоил на больших файлах (100 тыс. бай тов), если они были сильно фрагментированы (т.е. их части были беспорядочно разбросаны по всему диску). Редактирование прохо дило вполне успешно, но в определенный момент при перемещении курсора целый абзац внезапно исчезал. Подобные ситуации слишком трудно спрогнозировать. Но в данном случае это были совершенно реальные проблемы, на которые жаловались реальные пользователи, уплатившие приличные суммы и получившие за них головную боль. Для полного тестирования программы нужно проверить ее реакцию на каждую комбинацию допустимых и недопустимых значений в каждый момент ее работы и при всех возможных условиях. А это нереально. |