Файл: Отладка и тестирование программ: основные подходы и ограничения (Отладка программ).pdf
Добавлен: 28.03.2023
Просмотров: 172
Скачиваний: 4
ВВЕДЕНИЕ
В типичном процессе разработки программного обеспечения, независимо от конкретной модели разработки (например, каскадная, итеративная, спиральная и т. д.), для успешного выполнения проекта требуются определенные базовые действия, среди которых выделяются отладка и тестирование программного обеспечения.
Цель отладки – найти и исправить проблемный код, ответственный за симптом, нарушающий известную спецификацию. Отладка обычно происходит в ходе трех этапов разработки программного обеспечения, и степень детализации, необходимая для обнаружения дефекта, в каждом из этих трех этапов различается.
Первый этап – во время процесса кодирования, когда программист переводит спроектированный алгоритм в исполняемый код. Во время этого процесса ошибки, допущенные программистом при написании кода, могут привести к дефектам, которые необходимо быстро обнаружить и исправить до того, как будет выполнен переход к следующим этапам разработки. Чаще всего разработчик также выполняет модульное тестирование, чтобы выявить любые дефекты на уровне модуля или компонента.
Второе место для отладки – это более поздние этапы тестирования, включающие несколько компонентов или целую систему, когда может быть обнаружено неожиданное поведение, такое как неправильные коды возврата или аварийное завершение программы. Отладка на этом этапе необходима для того, чтобы сделать вывод, что тестируемая программа является причиной непредвиденного поведения, а не результатом плохого тестового примера из-за неправильной спецификации, несоответствующих данных или изменений в функциональной спецификации между разными версиями системы. После подтверждения дефекта следует отладка программы и определение неисправного компонента и требуемого исправления.
Третье место для отладки – развертывание, когда тестируемое программное обеспечение сталкивается с реальными условиями эксплуатации. Некоторые нежелательные аспекты поведения программного обеспечения, такие как неадекватная производительность при серьезной рабочей нагрузке или неудовлетворительное восстановление после сбоя, обнаруживаются на этом этапе, и перед крупномасштабным развертыванием необходимо найти и исправить проблемный код. Этот процесс также можно назвать локализацией дефекта.
Очевидно, что тестирование является необходимой областью для проверки программного обеспечения. Как правило, перед написанием программы в рамках статического тестирования проводятся проверки проекта и проверки кода [1.]. После написания кода можно применять различные методы статического анализа, основанные на исходном коде. Различные виды и этапы тестирования, нацеленные на разные уровни интеграции и различные режимы сбоев программного обеспечения, активно обсуждаются в специализированной литературе. Тестирование, проводимое на более поздних этапах (например, внешние функциональные тесты, системные тесты и т. д.), представляет собой тестирование «черного ящика», основанное на внешних спецификациях, и, следовательно, не требует глубокого понимания реализации. Обычно тестирование системы нацелено на ключевые аспекты продукта, такие как восстановление, безопасность, производительность, конфигурация оборудования, конфигурация программного обеспечения и т. д. [1.] Тестирование во время развертывания обычно включает определенный уровень критериев приемлемости для клиента. Многие компании-разработчики программного обеспечения выпускают предварительные версии (так называемые «бета»-версии) программ для достижения этой цели.
Таким образом, тестирование и отладка являются важнейшими действиями во время цикла разработки программного обеспечения. Тестирование выполняется для того, чтобы проверить, содержит ли программный код ошибки, а отладка необходима для обнаружения и исправления этих ошибок. Тестирование может быть ручным или автоматическим; при этом оно может быть разных типов: юнит-тестирование, интеграционное тестирование, системное тестирование, стресс-тестирование и т.д. Отладка также может быть ручной или автоматической.
Цели данной курсовой работы – рассмотреть основные принципы отладки и тестирования, получить подробное представление о методах тестирования, а также изучить механизмы отладки и тестирования на конкретных примерах. Для достижения цели в курсовой работе были поставлены следующие задачи:
- выяснить, из чего складывается общая методика отладки и тестирования программного обеспечения;
- выделить основные виды тестирования;
- получить представление о тестировании программ на конкретных примерах;
- применить полученные знания на практике.
1. Отладка программ
1.1 Общие правила и рекомендации
Отладка – один из самых творческих и интеллектуальных аспектов программирования, но в то же время она также может быть одним из самых неприятных моментов. В значительной степени проблемы, с которыми люди сталкиваются при отладке программ, носят не столько технический, сколько психологический характер. Чтобы стать успешным отладчиком, придется научиться думать по-другому. Подхода к отладке с помощью универсальной книги не существует, хотя, вероятно, могут помочь «11 истин об отладке» Ника Парланте [8.].
Успешная отладка требует принятия различных стратегий и целей, и часто бывает трудно переключить точку зрения с одной на другую. Хотя отладка часто бывает очень сложной, ее всегда можно выполнить. Иногда для этого потребуется все имеющиеся в распоряжении навыки и творческий подход. Отладка – важный навык, который необходимо использовать каждый день, занимаясь теоретической информатикой (и тем более программированием). В этом случае придется планировать работу заранее и выделять достаточно времени для тестирования и отладки, поскольку это принципиально важно для создания качественного программное обеспечение. Кроме того, следует сосредоточить усилия на развитии этих навыков на ранних этапах обучения программированию, поскольку они станут еще более важными, когда написание программ станет более трудоемким и дорогостоящим процессом.
Ниже приведены основные правила [7.] отладки.
-
-
-
- Интуиция и предчувствия прекрасны – следует просто проверить их. Когда догадка и факт сталкиваются, факт побеждает.
- Не следует искать сложных объяснений. Даже простейшее упущение или опечатка могут привести к очень странному поведению написанной программы. Каждый способен время от времени совершать чрезвычайно простые и очевидные ошибки. Как бы то ни было, всегда необходимо смотреть на код критически и не бросать взгляд на серию простых утверждений, полагая, что они слишком просты для того, чтобы в них можно было ошибиться.
- Ключ к разгадке того, что не так в написанном коде, заключается в значениях переменных и потоке управления. Для поиска ошибок требуется увидеть, на что конкретно указывают факты. Компьютер не пытается ввести в заблуждение.
- Нужно быть систематичным и настойчивым. Ошибка не перемещается по коду, не пытается обмануть или уклониться. Она просто сидит в одном и том же месте и каждый раз заставляет делает все то же самое неправильно.
- Если код работал минуту назад, а теперь нет, то что в нем было изменено в последнюю очередь? Это невероятно надежное эмпирическое правило – причина, по которой код принято тестировать фрагментарно на ходу, а не весь сразу.
- Не следует изменять код случайным образом, всякий раз пытаясь отследить ошибку. На этапах отладки и тестирования не следует применять аналогию с ученым, который одновременно изменяет более одной неизвестной в эксперименте. Такой подход значительно усложняет интерпретацию наблюдаемого поведения и приводит к появлению новых ошибок.
- Если будет обнаружен неправильный код, который, похоже, никак не связан с отслеживаемой ошибкой, все равно следует исправить неправильный код. Неправильный код так или иначе может быть связан с ошибкой или же скрывать ее так, как нельзя себе представить.
- Нужно быть быть в состоянии объяснить в стиле Шерлока Холмса серию фактов, тестов и выводов, которые привели к обнаружению ошибки. В качестве альтернативы, если есть ошибка, но не получается ее точно определить, нужно иметь возможность подробно объяснить, почему каждая из написанных функций не может содержать ошибку. Один из этих аргументов будет содержать ошибку, поскольку одна из функций действительно содержит ошибку. Попытка построить аргументы всегда может помочь увидеть недостаток.
- Следует критически относиться к собственным убеждениям о написанном коде. Практически невозможно увидеть ошибку в функции, если есть стойкая убежденность в том, что функция написана верно и не является причиной ошибки. Только когда факты безоговорочно доказали, что функция не является источником проблемы, ее можно считать правильной.
- Несмотря на то, что нужно использовать эмпирический подход, все еще остается огромное пространство для убеждений, догадок, предположений и т. д. Не стоит пренебрегать своей интуицией относительно того, где, вероятно, находится ошибка. В первую очередь следует проверить функции, на которых падает подозрение.
- Отладка зависит от объективного и аргументированного подхода, которые связаны с общей перспективой и пониманием работы написанного кода. Отладка кода требует даже большего умственного труда, чем написание кода. Чем дольше предпринята безуспешная попытка найти ошибку, тем меньше будет реальной перспективы это сделать. Очень часто программист может часами искать ошибку поздно ночью, чтобы окончательно сдаться в четыре часа утра, и на следующий день найти ошибку за десять минут. Что позволило так быстро найти ошибку на следующий день? Может быть, просто нужно было немного поспать и получить определенное время для более свежего взгляда на вещи. Или, может быть, подсознание обнаружило дефекты во время сна. В любом случае сценарий «займись чем-нибудь еще, вернись и немедленно найди ошибку» довольно часто имеет место [13.].
-
-
1.2 Отладка программ на языке Python
Для поиска дефектов в программах на языке Python можно использовать не только функцию print, но и специализированные утилиты. Большое количество возможностей, предоставляемых отладчиками, позволит сэкономить время и упростить отладку [5.].
Вызов функции print многие разработчики используют для отображения информации, которая помогает понять, что происходит в коде. Самая большая проблема в использовании print связана с необходимостью вносить изменения в код и перезапускать приложение, чтобы увидеть изменения.
В языке Python есть встроенный отладчик под названием pdb. Это простая консольная утилита, которая обладает основной функциональностью для отладки кода [13.]. Для поиска более интерактивного отладчика следует обратить внимание на ipdb – отладчик с функциональностью из IPython.
Проще всего вызвать pdb из кода: import pdb; pdb.set_trace()
Как только интерпретатор доберётся до этой строчки, запустится отладчик и в консоли будут доступны новые команды.
list(l)
Эта команда покажет часть кода, на выполнении которой сейчас находится интерпретатор. Можно передать два аргумента first и last для просмотра определённого участка кода. Если указать только first, то будет выведен код вокруг искомой строки.
up(p) и down(d)
Эти команды используются для передвижения по стеку вызовов. С их помощью можно отследить, откуда была вызвана текущая функция.
step(s) и next(n)
Другая пара не менее важных команд. С их помощью можно выполнять код построчно. Единственное различие между ними в том, что next(n) перейдёт к следующей строке вне зависимости от вызываемых функций, а step(s) перейдёт в вызванную функцию, если это возможно.
break(b)
Эта команда позволяет создавать брейкпоинты без внесений изменений в код.
Краткий список команд pdb:
args(a) – выводит аргументы функции;
continue(c) или (cont) – продолжит выполнение до первого брейкпоинта или до завершения программы;
help(h) – выводит список доступных команд или подсказки по определённой команде;
jump(j) – перепрыгивает к выполнению указанной строчки кода;
list(i) – выводит исходный код программы вокруг выбранной строки;
expression(p) – выводит значение выражения;
pp – выводит значение в «красивом» виде;
quit или exit(q) – отменяет выполнение программы;
return(r) – завершает выполнение текущей функции.
2. Тестирование программ
2.1 Основные причины для организации тестирования
Обратная связь — это данные, которые с выхода поступают на вход. Ее типы [11.]:
- Положительная обратная связь, которая усиливает сигнал на выходе. В случае разработки это [17.]
-
-
- положительные отзывы конечных пользователей;
- запросы пользователей на новую функциональность;
- увеличение объема продаж.
-
-
- Отрицательная обратная связь гасит сигнал. Имеют место [5.]
негативные отзывы конечных пользователей;
отсутствие интереса к программному продукту;
падение объема продаж.
К сожалению, отрицательная обратная связь обычно поступает слишком поздно. Тут-то и нужен тестировщик [4.] – человек, который даёт участникам проекта по разработке программного обеспечения отрицательную обратную связь о качестве программного продукта на самой ранней стадии, когда ещё не поздно всё исправить.
Тестирование (Quality Control) – это проверка соответствия между реальным и ожидаемым поведением программы, которая проводится на конечном наборе специально выбранных тестов [2.].
Обязанности тестировщика [12.]:
- находить дефекты («баги»);
- вносить описание найденного дефекта в систему отслеживания ошибок (Bug tracking system);
- описывать способы воспроизведения ошибок;
- создавать отчёты о тестировании для каждой версии продукта;
- (дополнительно) читать и исправлять документацию;
- (дополнительно) анализировать и уточнять требования к программе;
- (дополнительно) создавать программное обеспечение для автоматизации процесса тестирования. Главный результат работы тестировщика – повышение качества программного обеспечения [19.]. Аспекты качества программы [18.]:
- Функциональность:
- пригодность к использованию;
- правильность выполнения задачи;
- поддержка стандартов;
- защищенность (security).
- Надёжность:
- низкая частота отказов;
- отказоустойчивость;
- способность к восстановлению.
- Практичность (user-friendly):
- понятность в использовании;
- управляемость;
- привлекательность.
- Эффективность:
- время отклика программы;
- объём использования ресурсов ПК.
- Сопровождаемость;
- Переносимость.