Методы и средства обработки и тестирования программного обеспечения
Различие между отладкой и тестированием программы, возможные ошибки и оценка правильности работы. Средства и методики отладки, подходы к данному процессу. Рекомендации по тестированию программ, анализ полноты проверки, определение необходимости повтора.
Рубрика | Программирование, компьютеры и кибернетика |
Вид | курсовая работа |
Язык | русский |
Дата добавления | 02.12.2011 |
Размер файла | 67,0 K |
Отправить свою хорошую работу в базу знаний просто. Используйте форму, расположенную ниже
Студенты, аспиранты, молодые ученые, использующие базу знаний в своей учебе и работе, будут вам очень благодарны.
Размещено на http://www.allbest.ru/
Размещено на http://www.allbest.ru/
1. Отладка программ
Мало, в какой области деятельности имеется столько возможностей для ошибок, как в программировании. Искусство локализации таких ошибок, когда факт их существования установлен, носит название отладки. Таким образом, отладка программы предполагает обязательное наличие той или иной ошибки; в противном случае мы имеем дело с тестированием.
Одним из критериев профессионального мастерства программиста является их способность обнаруживать и исправлять собственные ошибки: начинающие программисты не умеют этого делать, у опытных программистов это не вызывает затруднений. Тем не менее, ошибки в программах делают все.
Программистов часто учат программированию, но редко - отладке. А поскольку отладка программы поглощает больше времени, чем ее первоначальное написание, и является делом более трудным, приходится только сожалеть, что обучению искусству отладки не уделяют должного внимания. В общем времени разработки программы отладка занимает, по оценкам специалистов, от 50 до 90%. Написание программы схоже с написанием отчета: и в том и в другом случае необходимы предварительный вариант (до выявления ошибок) и окончательный вариант (после их устранения). Редко бывает так, чтобы предварительный вариант отчета или программы стал сразу и окончательным вариантом.
По вопросам отладки программ имеется сравнительно немного работ. Отладку обычно называют искусством, с тем, чтобы избежать решения трудной задачи обучения этому делу.
Процесс отладки зависит от условий функционирования программы, т.е. от используемой машины, языка программирования, операционной системы, специфики самой задачи и даже от особенностей конкретной программы.
Можно с определенностью утверждать, что каждый язык, компилятор и машина связаны с определенными типами дефектов программ и ошибок программирования. Простейшим примером являются синтаксические ошибки, которые в очень сильной мере предопределяются конкретным языком программирования. Однако мы располагаем весьма немногочисленными данными относительно взаимосвязи между тем или иным языком, возможным количеством ошибок и степенью сложности их обнаружения.
1.1 Различие между отладкой и тестированием
Многие программисты путают отладку программ с тестированием, предназначенным для проверки их работоспособности. Отладка имеет место тогда, когда программа со всей очевидностью работает неправильно. Поэтому отладка начинается всегда в предвидении отказа программы. Если же оказывается, что программа работает верно. То она тестируется. Часто случается так, что после прогона тестов программа вновь должна быть подвергнута отладке. Таким образом, тестирование устанавливает факт наличия ошибки, а отладка выявляет ее причину, и эти два этапа разработки программы перекрываются. На каждый из них должно специально выделять время, с тем, чтобы подчеркнуть необходимость выполнения обоих указанных этапов создания программы.
1.2 Из истории ошибок
Бытует мнение, что первая программная ошибка была обнаружена на заре развития ЭВМ, когда в Массачусетском технологическом институте окончилась неудачей попытка запуска машины Whirlwind I. Неистовая проверка монтажа, соединений и оборудования не выявила никаких неисправностей. Наконец, уже отчаявшись, решили проверить программу, представляющую собой маленькую полоску бумажной ленты. И ошибка была обнаружена именно в ней - в этом программистском ящике Пандоры, из которого на будущие поколения программистов обрушились беды, связанные с ошибками программы.
1.3 Ошибки в описании задач
Обычно получается так, что, когда программа написана, пользователь обнаруживает несоответствие выдаваемых ею результатов желаемым. Подобная ситуация может складываться как из-за отсутствия взаимопонимания между программистами и пользователями, так и от того, что пользователи в действительности не знают, чего они хотят. Если при этом неверно работающая программа помогает пользователю понять свои потребности, а программисту уяснить истинные пожелания пользователя, то еще не все потеряно.
Иногда неверные результаты могут послужить толчком к тщательному пересмотру первоначальной постановки задачи. Некачественное определение требований к программе приводит к созданию программы, которая будет правильно решать неверно сформулированную задачу. В таких случаях, как правило, требуется полное перепрограммирование. При этом необходимо настаивать на составление нового графика разработки программы, поскольку она должна быть полностью переделана. Не позволяйте неверной программе занимать все ресурсы (время программирования, машинное время и т.п.), так как должна быть создана новая программа, и этот процесс должен быть запланирован вновь.
Признаком того, что создаваемая для какого-либо заказчика программа может оказаться не соответствующей его истинным потребностям, служит ощущение неясности задачи. В этом случае во избежание написания «неправильной» программы лучше всего четко зафиксировать, что она должна делать, и привести пример. Письменная регистрация требований к программе заставляет заказчика собраться с мыслями и дать достаточно точное определение требований. Всякие устные указания являются заведомо ненадежными и часто приводят к взаимному недопониманию.
1.4 Ошибки в выборе алгоритма
Как только задача до конца определена, программист начинает искать возможный алгоритм или метод ее решения. К сожалению, при этом он может выбрать неподходящий или неэффективный алгоритм, и тогда весь процесс выбора придется повторять сначала.
Примером неподходящего выбора может служить принятие итеративного расходящегося метода решения некоторого уравнения в то время, когда некоторый другой метод мог бы обеспечить получение точного результата. В качестве примера неэффективного, плохо подобранного алгоритма можно назвать способ решения задачи, который дает точный ответ, но требует больший затрат времени. К сожалению, часто плохой выбор алгоритма становится очевидным лишь после его опробования, однако, несмотря на это. Все же следует уделять и внимание, и время выбору алгоритма, с тем, чтобы впоследствии не приходилось переделывать каждую программу. По методам программирования имеется совсем немного книг, и в некоторых из них содержится описание конкретных алгоритмов. Читатель, желающий избежать выбора некорректных алгоритмов, должен быть хорошо знаком с литературой по своей специальности.
1.5 Ошибки анализа
Эти ошибки связаны либо с неполным учетом могущих возникнуть ситуаций, либо с неверным решением задачи. К первому случаю относится, например, пренебрежение возможностью появления отрицательных значений переменных, малый и больших величин. Во втором случае обычно имеют место крупные и мелкие логические ошибки, из которых можно назвать:
- отсутствие задания начальных значений переменных;
- неверные условия окончания цикла;
- неверная индексация цикла;
- отсутствие заданий условий инициирования цикла;
- неправильное указание ветви алгоритма для продолжения процесса решения задачи.
Самый лучший способ организации отладки - это сведение к минимуму необходимости в ней. Вдумчивая разработка функциональной структуры программы, сопровождаемая достаточно подробной блок-схемой или кратким описанием, обеспечивает условия для лучшего кодирования программ.
Блок-схемы помогают избежать многих ошибок, и, кроме того, их можно использовать в качестве вспомогательного средства выявления ошибок при отладке. Метод проверки правильности блок-схемы заключается в том, что через несколько дней после ее составления программист повторно обращается к описанию задачи и набрасывает блок-схему заново. Затем сличают оба варианта. Такой шаг на первый взгляд может показаться пустой тратой времени, однако всякая ошибка на уровне алгоритма может в дальнейшем обернуться катастрофой и повлечь основательный пересмотр программы.
1.6 Ошибки общего характера
После того как найден подходящий алгоритм решения задачи, на этапы программирования все же могут появиться ошибки независимо от выбранного языка. Такими ошибками могут быть:
- ошибки из-за недостаточного знания или непонимания программистом языка программирования или самой машины;
- ошибки, допущенные при программировании алгоритма, когда команды, использованные в программе, не обеспечивают последовательности событий, устанавливаемой алгоритмом;
- синтаксические ошибки;
- ошибки при выполнении синтаксически правильных операторов;
- ошибки, вызванные неверными данными.
Все указанные ошибки общего характера, за исключением синтаксических, могут быть обнаружены посредством тестирования, в результате которого работа над программой возвращается в стадию отладки; разновидности рассмотренных выше ошибок и соответствующие примеры приведены в таблице 1.
Таблица 1. Характерные ошибки программирования
Вид ошибок |
Пример |
|
1. Неправильная постановка задачи |
Правильное решение неверно сформулированной задачи |
|
2. Неверный алгоритм |
Выбор алгоритма, приводящего к неточному или неэффективному решению задачи |
|
3. Ошибки анализа |
Неправильное программирование алгоритма |
|
4. Семантические ошибки |
Непонимание порядка выполнения команды |
|
5. Синтаксические ошибки |
Нарушение правил, определяемых языком программирования |
|
6. Ошибки при выполнении операций |
Отсутствие указаний на ограничивающие условия вычислений (деление на нуль и т.п.) |
|
7. Ошибки в данных |
Неудачное определение возможного диапазона изменения данных |
|
8. Ошибки в документации |
Документация пользователя не соответствует действующему варианту программы |
Последний из указанных в таблице 1 видов ошибок может быть связан либо с самой программой, либо с документацией на нее.
Наконец, существует еще один вид ошибок, который называют глитчем (хроническим дефектом). Термин «глитч» применяется для указания того факта, что программы не удовлетворяют некоторым требованиям, но эти требования не были сформулированы в задании на разработку программ.
1.7 Ошибки физического характера
тестирование программа проверка ошибка
Можно назвать восемь типов ошибок, вызываемых неверными действиями программиста:
1) Пропуск некоторых строк.
2) Перестановка строк программы.
3) Появление лишних строк (например, в результате того, что оказались не вычеркнутыми скорректированные строки).
4) Отсутствие необходимых данных.
5) Непредусмотренные данные.
6) Неверный формат данных.
7) Отсутствие операторов управления заданиями.
8) Использование неверной распечатки программы.
Все перечисленные ошибки обнаружить гораздо сложнее, так как, например, пропуск или перестановка строк программы могут не привести к возникновению легко распознаваемых синтаксических ошибок.
Во избежание ошибок в данных они должны тщательно контролировать в процессе редактирования и выводиться на печать, что подразумевает распечатывание всей введенной информации.
1.8 Правильность программы
Любые программы правильны в отношении их логического построения только для определенного типа данных. Например, программа нахождения наибольшего общего делителя двух чисел верна лишь в том случае, когда оба числа целые. Если же подать на вход такой программы нуль или дробное число, нормальная работа программы нарушится. Поэтому необходимо четко определять область значений данных, в которой программа способна функционировать, и вводить операторы, позволяющие проверять, находятся ли данные в установленных границах.
Чтобы программу можно было применять, прежде всего, она должна быть правильной, а нарушение правильности может проявляться двумя способами: либо неверна синтаксическая конструкция программы, либо программа выдает неверные результаты. Правильность синтаксиса означает, что должны быть точно сформированы наименования переменных, арифметические и логические операции должны подчиняться определенным синтаксическим правилам и т.п.
1.9 Синтаксические шибки
Выявление транслятором синтаксических ошибок представляет собой самый важный и, безусловно, необходимый этап отладки программы. Чем больше ошибок обнаруживается и исправляется на этом этапе, тем легче оказываются отладка и тестирование в дальнейшем. Начинающий программист наивно полагает, что на этапе компилирования выявляются все ошибки. Более опытный и придирчивый программист знает, что многие «хитрые» синтаксические ошибки транслятору обнаружить не под силу, и поэтому стремится обеспечить наиболее полное диагностирование таких ситуаций с выдачей в каждом конкретном случае подробной информации об ошибках.
Если под синтаксической ошибкой понимать «всякое нарушение требований языка программирования», то следует признать, что многие такие ошибки остаются необнаруженными. Это имеет место, например, при отсутствии указания начального значения какой-либо переменной, при наличии ответвления алгоритма в середину цикла оператора DO и в случае нарушения правил индексации. Результаты таких операций непредсказуемы, и если выполнить компилирование программы с такими ошибками, она будет работать самым таинственным образом. Выявление таких ошибок может оказаться делом нелегким. Отсутствие сообщений компьютера о синтаксических ошибках является необходимым, но не достаточным условием, чтобы считать программу правильной.
Обнаружение синтаксических ошибок важно по той причине, что они непременно приводят к затруднениям при выполнении программы. Более того, для компилятора требуется, чтобы эти ошибки были исправлены еще до начала работы программы.
В качестве примеров синтаксических ошибок в одном операторе можно назвать:
- пропуск необходимого знака пунктуации;
- несогласованность скобок;
- пропуск нужных скобок;
- неправильное формирование оператора;
- неверное образование имен переменных;
- неправильное использование арифметических операторов;
- неверное написание зарезервированных слов.
Примерами синтаксических ошибок, охватывающих взаимодействие двух и более операторов, могут служить:
- противоречивые команды;
- отсутствие условий окончания цикла;
- дублирование или отсутствие меток;
- отсутствие описания массива;
- запрещенный переход.
Если компилятор детально не анализирует взаимодействия двух или более команд, то нередко указанные выше ошибки остаются необнаруженными. Так, например, некоторые компиляторы не выдают программисту сообщений о непредусмотренном входе в цикл оператора DO.
Среди ошибок, которые часто выявляются компилятором в результате контроля синтаксической структуры программы, следует упомянуть неописанные или неправильно описанные переменные опечатки и использование запрещенных символов.
Большинство синтаксических ошибок зависит от применяемого языка, поэтому мало, что можно сказать конкретно по поводу способов их исправления в каждом конкретном случае. Однако можно указать некоторые общие принципы, которыми следует руководствоваться.
Во-первых, если в программе выявлено очень большое количество ошибок, следует просто исправить очевидные ошибки и повторить компиляцию. Некоторые сообщения о синтаксических ошибках являются на самом деле ложными, так как вызваны другими синтаксическими ошибками, и поэтому не стоит тратить много времени на то, чтобы разобраться в выданном сообщении, если характер ошибки не очевиден сразу. Ложные сообщения об ошибках особенно часты тогда, когда в программе имеет место какое-то серьезное упущение, например отсутствие описания переменной или массива.
Во-вторых, обращайтесь без колебаний к соответствующему руководству по программированию на данном языке: при неявных синтаксических ошибках чтение раздела, касающегося синтаксических правил для конкретных операторов, обычно приводит к выявлению допущенной ошибки.
В-третьих, большое влияние на объем работ по отладке оказывает выбор компилятора. Хороший отладочный компилятор может зачастую обеспечить сокращение затрат времени наполовину. Специальный отладочный компилятор обнаруживает больше ошибок, чем обычный, поскольку он детально анализирует синтаксическую конструкцию и взаимодействие команд. Но еще важнее то, что в процессе выполнения исходной программы отладочный компилятор производит многочисленные проверки, выявляющие переменные, для которых не заданы начальные значения, неправильные индексы и запрещенные переходы. Разумеется, эти дополнительные проверки требуют большего времени, и поэтому процесс компилирования программы обычно осуществляется гораздо медленнее по сравнению с обычным компилятором.
Однако отладочные компиляторы не поставляются изготовителями ЭВМ в составе, их программного обеспечения, их следует приобретать отдельно. Что касается стоимости таких компиляторов, то здесь оправданны любые затраты, так как если предположить, что отладка занимает 70% рабочего времени программиста и значительную долю машинного времени, то становится ясной быстрая окупаемость затрат на хороший отладочный компилятор.
Ошибки, не обнаруживаемые компилятором
Существует множество ошибок, которые компилятор не в состоянии выявить, если используемые в программе соответствующие операторы сформированы правильно. Примерами таких ошибок являются:
- пропуск части программы;
- переход не на ту ветвь, на которую нужно, после выполнения оператора условного перехода;
- использование неверного формата в операциях ввода данных;
- неправильные параметры циклов (начальное состояние, приращение или конечное состояние);
- неполная или неправильная индексация массива;
- выпадение из рассмотрения некоторых возможных ситуаций, связанных с данными вычислениями.
Среди других ошибок, не выявляемых при компилировании следует назвать неправильный тип фактического параметра в операторах вызова, т.е. случаи, когда некоторая подпрограмма настроена, скажем, на целочисленный аргумент, а ей передается действительное число. Ошибку такого вида компилятор обнаружить не в состоянии, поскольку каждая из подпрограмм может компилироваться отдельно и в распоряжении компилятора нет информации, позволяющей проверить, совместимы ли типы аргументов вызываемой и вызывающей программ. Ошибку рассматриваемого вида можно выявить в процессе выполнения программы, либо если компилятором фиксируется информация относительно типа переменных, либо при использовании хорошего отладочного компилятора.
Приведем еще несколько типов ошибок, которые могут выявляться (но редко выявляются) компилятором:
- неиспользуемые метки;
- неописанные переменные;
- описанные, но не используемые переменные;
- неверный тип аргумента функции.
Все эти ошибки могут быть обнаружены на этапе компилирования. Некоторые другие ошибки, возможно, выявить только в ходе выполнения программы. Ряд компиляторов позволяет генерировать вспомогательные блоки объектных программ (например, блок проверки диапазона изменения индексов), служащие для последующего контроля над ошибками определенного характера при выполнении программы. Чем больше имеется таких контрольных блоков, тем менее трудоемкой оказывается работа, связанная с устранением ошибок.
1.10 Виды отладки
Отладка начинается с того момента, когда перестают выдаваться сообщения о синтаксических ошибках. В начале процесса отладки надо использовать простые тестовые данные. Если при этом получаются верные результаты, следует переходить к тестированию программы посредством более сложных данных. В случае если результаты неверны, возможны следующие ситуации:
- Синтаксических ошибок нет, но программа не скомпилирована.
- Программа скомпилирована, работает, но не выдает результатов.
- Программа скомпилирована, работает, но происходит преждевременный останов.
- Программа скомпилирована, работает, но выдает неправильные результаты.
- Программа зациклилась.
СЛУЧАЙ 1. КОМПИЛИРОВАНИЕ НЕ ЗАВЕРШЕНО
Подобная ситуация встречается сравнительно редко и свидетельствует о наличии какой-то принципиальной ошибки в программе. В этом случае обычно появляются сообщения о тех или иных системных ошибках, которые можно использовать в качестве вспомогательного средства для выявления имеющейся ошибки. Однако, как правило, интерпретация таких сообщений трудна и требует большого практического опыта.
Для обнаружения ошибки можно попытаться изолировать ошибку. Для этого программу разбивают на более мелкие самостоятельные сегменты и делают попытку компилировать их по отдельности. В таком сегментированном виде программа сохраняется до момента окончания компилирования всех сегментов. После этого начинается их последовательная увязка, и сегменты присоединяются до тех пор, пока не выявится факт прекращения компилирования программы; последний добавленный сегмент и будет тем блоком, который содержит ошибку. Путем тщательного анализа этого дефектного блока или посредством дальнейшего его сегментирования можно, в конце концов, выявить тот оператор, который препятствует компилированию программы. Однако применение описанного метода нежелательно, и он должен использоваться лишь в крайних случаях: предпочтительнее обратиться за помощью к своим более опытным товарищам по работе.
СЛУЧАЙ 2. БЕЗРЕЗУЛЬТАТНАЯ РАБОТА ПРОГРАММЫ
Когда программа работает, но не выдает никаких результатов, от нее мало проку, хотя это и некий прогресс по сравнению с первым случаем. Такие неполадки могут вызываться какими-либо логическими или системными ошибками. Примером логической ошибки может служить ситуация, когда программа начинает работу и сразу уходит на ветвь окончания выполнения задания, не сформировав никакого результата для выдачи. Ошибки подобного рода могут быть обнаружены с помощью методов, описанных ниже при рассмотрении проблемы обнаружения ошибок.
Системная ошибка имеет своей первоосновой некоторую программную ошибку, которая заставляет операционную систему прервать процесс выполнения программы. Сигнал прерывания может исходить от оборудования, самой операционной системы или скомпилированной программы. При этом обычно сообщается код системной ошибки, а может быть, и некоторая информация о ее характере. Однако сообщения о системных ошибках крайне таинственны и не содержат информации о том, где допущена ошибка. Если же при этом выдан какой-либо результат, то имеется все же какое-то указание на местоположение ошибки, и задача сводится к тому, чтобы сузить «подозрительную» область либо посредством использования отладочных протоколов, либо с помощью анализа отладочных результатов.
К программным ошибкам, приводящим к системным ошибкам, относятся деление на нуль, обращение к области данных и восприятие их как инструкций программы, неверная индексация массива и др.
Обнаружение ошибок в случаях отсутствия результатов работы программы и незавершенного компилирования иногда может оказаться делом чрезвычайно трудным. Один из возможных здесь подходов - перепрограммирование конкретного сегмента некоторым другим способом, приводящим к достижению той же цели. Если характер ошибки не очевиден, указанный подход может представлять собой наилегчайший путь к ее устранению. Схож с ним и другой подход, при котором создается несколько копий неправильно функционирующего блока, и в них осуществляются различные изменения, сопровождаемые повторным компилированием. Этот процесс повторяется до тех пор, пока ошибка не исчезнет или не окажется изолированной.
СЛУЧАЙ 3. ПРЕЖДЕВРЕМЕННЫЙ ОСТАНОВ
Эта ситуация характерна тем, что программа компилируется до конца, начинается ее выполнение, выдаются какие-то результаты, но затем работа программы прекращается раньше, чем это должно быть. Налицо явный прогресс по сравнению с двумя первыми случаями, и положение дел обычно облегчается наличием некоторой информации на выходе. Благодаря этому здесь можно применять традиционные методы отладки.
Ошибки, приводящие к преждевременному прекращению работы программы и сопровождаемые затем сообщением о системной: ошибке, называют взрывами (blowup) или воронками (cratered). Это тяжелые ошибки, так как они не дают возможности продолжать выполнение программы.
СЛУЧАЙ 4. НЕВЕРНЫЕ РЕЗУЛЬТАТЫ
Когда программа работает, но выдает неверные результаты, опытные программисты всегда считают это удачей. Достижение этой стадии говорит о том, что программа в принципе правильна, а ее логика работает почти точно.
СЛУЧАЙ 5. ЗАЦИКЛИВАНИЕ
Этот вид ошибок, как правило, обнаружить не так уже трудно. Если сразу не удается распознать, в каком цикле имеется ошибка, следует просто добавить в программу операторы печати до и после каждого «подозрительного» цикла. При этом, однако, следите за тем, чтобы указанные операторы не оказались встроенными внутрь цикла: в противном случае на печать начнут выдаваться тысячи строк. Добавленные надлежащим образом операторы печати обеспечат выдачу соответствующих данных, которые покажут, из какого цикла при наличии входа не производится выход.
1.11 Обнаружение ошибок
Часто обнаружение той или иной ошибки в программе оказывается делом довольно трудным. Мы приходим к мысли о том, что в программу закралась ошибка, в одной из следующих ситуаций:
1. Отсутствует уверенность в том, что программа начала выполняться.
2. Программа начала выполняться, но произошел преждевременный останов с выдачей или без выдачи сообщения о системной, ошибке.
3. Программа начала выполняться, но зациклилась, о чем можно судить по ее чрезмерно долгой работе.
4. Программа выдала неправильную информацию.
Любая из этих ситуаций требует от программиста проверки последовательности выполнения команд программы.
Если ошибка оказывается непонятной и ее место положение не обнаружено, можно повторить компиляцию программы и посмотреть, появится ли та же ошибка снова. Большинство ошибок воспроизводимо, и этот шаг, по крайней мере, подтвердит вам, что ошибка, в программе есть. Неповторяющиеся ошибки могут быть вызваны неправильным действием оператора ЭВМ, сбоем в работе оборудования, колебаниями питающего напряжения или тупиковыми ситуациями в операционной системе. О таких ошибках надо сохранять какие-то записи, поскольку часто они возникают в случайные моменты времени. Одна из возможных причин неповторяющихся ошибок - наличие в программе неопределенных переменных. Регистрировать факты появления таких ошибок можно, например, посредством внесения дополнительных примечаний в документацию и хранения сообщения об ошибке на будущее.
Выявление поведения некоторого неизвестного блока в программе означает, прежде всего, необходимость выработки стратегии поиска. В одних случаях (например, когда единственной выходной информацией является сообщение об ошибке) вообще отсутствуют какие-либо сведения, позволяющие выявить ошибку. В других (например, когда выдан некоторый результат) программист все-таки располагает некоторыми данными о местоположении ошибки. Обычно не представляет труда исправить ошибку, если известно, где она находится.
Иногда бывает полезно исключить из рассмотрения маловероятные причины ошибок. Когда вы сталкиваетесь с какой-либо ошибкой или неполадкой, прежде всего, следует решить, что тому виной: технические средства, операционная система, компилятор или ваша собственная программа? Если вы не работаете на новом оборудовании и не имеете дело с новым программным обеспечением, то большинство ошибок - ваши собственные ошибки.
Удостоверившись в наличии программной ошибки, вы можете действовать далее по методу последовательного исключения. Если - вы получаете распечатки вводимых данных, то подпрограммы вводя да, скорее всего, работают нормально. Аналогично могут быть исключены из рассмотрения некоторые другие подпрограммы, и область поиска постепенно сузится до двух-трех «подозрительных» блоков, которые и подвергаются более глубокому анализу. Главный принцип в работе по обнаружению ошибки - это недопущение беспорядочного поиска, к которому склонны многие неопытные программисты.
Полезно иметь в виду, что поиск ошибок необходимо начинать с рассмотрения в первую очередь простых ситуаций. Например, если вы считаете, что ошибка располагается в какой-то из трех подпрограмм и проверка каждой из них занимает соответственно 10 мин, 2 ч и 3 дня, то явно имеет смысл проанализировать сначала две первые подпрограммы, так как при этом есть возможность подучить желаемый результат за короткое время. (Следует заметить, что обычно руководствуются именно этим неписаным правилом.)
Цель программиста состоит в том, чтобы продолжать сужение области поиска до полного выявления ошибки. Поскольку одни блоки программы могут характеризоваться нулевой вероятностью наличия в них ошибки, а другие - довольно высокой, задача заключается в постепенном увеличении вероятности определения местоположения ошибки до 100%.
Общепринятый метод отыскания ошибок в программе предполагает введение в нее от 5 до 10 специальных отладочных операторов. Один из них должен находиться в начале программы, другой - в конце, а остальные следует располагать внутри программы равномерно, но избегая попадания их внутрь циклов. Следует размещать один оператор до начала цикла и один после его окончания; в противном случае соответствующая информация будет выдаваться на печать каждый раз при выполнении цикла, и нетрудно представить себе случай, когда цикл повторяется не одну тысячу раз.
Однако с отысканием неверно действующего оператора работа по устранению ошибки зачастую не заканчивается, поскольку обычно оказывается, что причина ошибки находится где-то в другом месте программы.
Процесс обнаружения ошибок характеризуется выявлением двух мест в программе: точки обнаружения и точки происхождения. Точка обнаружения - это место в программе, где ошибка себя проявляет или становится очевидной. Точка обнаружения должна выявляться первой.
Точка происхождения - это место в программе, где возникают условия для появления ошибки.
1.12 Утверждения
Некоторые новые экспериментальные языки программирования предоставляют возможность введения утверждений, позволяющих оговаривать условия, требуемые для правильной работы конкретной программы. Чаще всего встречаются два типа утверждений: глобальные, которые содержатся вместе с описателями, и локальные, располагающиеся внутри программы и позволяющие оговаривать определенные значения переменных в данной точке выполняемой программы. Примером условий первого типа служит объявление N в качестве целочисленной переменной и утверждение о том, что она должна всегда принимать положительные значения. Примером утверждения второго типа является условие, что еженедельная плата не должна превышать 2000 долл.
Если какое-нибудь из утверждений не выполняется, программа прекращает работу и выдает сообщение об ошибке. Утверждения второго типа можно легко встраивать в программу с помощью оператора IF. Некоторые языки предоставляют программисту возможность вводить утверждения, на основе которых при компилировании формируется соответствующий контрольный блок программы; в рабочем режиме утверждения трактуются как комментарии.
1.13 Список характерных ошибок
Для подавляющего большинства программистов характерно систематическое повторение в разных программах ошибок определенного типа. Это может быть использование неразрешенных индексов, неправильное применение операторов условного перехода, установление начального значения, равного единице, там, где оно должно быть равно нулю, и т.п. Повторение ошибок наблюдается особенно часто в тех случаях, когда программист работает с двумя или более языками: поскольку каждый язык имеет свои правила, их легко перепутать. Во избежание такой ситуации программисту полезно иметь список своих характерных ошибок, который он может использовать в качестве вспомогательного средства отладки.
Ниже приводятся две категории наиболее распространенных ошибок программирования. К первой из них относятся ошибки общего (несинтаксического) характера, которые остаются в программах после выполнения синтаксического контроля. Вторая категория включает ошибки специального вида, которые особенно трудны для выявления.
ОШИБКИ ОБЩЕГО ХАРАКТЕРА
Логические ошибки
1. Неверное указание ветви алгоритма после проверки некоторого условия.
2. Неполный учет возможных условий.
3. Пропуск в программе одного или более блоков составленного алгоритма.
4. Ответвление по неверной метке.
Ошибки в циклах
1. Неправильное указание начала цикла.
2. Неправильное указание условий окончания цикла.
3. Неправильное указание числа повторений цикла.
4. Неверное индексирование цикла.
5. Бесконечные или замкнутые циклы.
Ошибки при работе с данными
1. Определение не всех возможных типов данных.
2. Отсутствие редактирования неверных данных.
3. Организация считывания меньшего или большего объема данных, чем требуется.
4. Неправильное редактирование данных или несоответствие действительных полей данных их описаниям.
Ошибки в описании переменных
1. Использование переменных без указания их начальных значений.
2. Не предусмотрено изменение содержимого счетчика или накопителя.
3. Неправильная установка значения программного ключа.
4. Использование неверного наименования переменной (т.е. ошибочное указание другой переменной).
Ошибки при работе с массивами
1. Отсутствие возможности присвоения нулевого значения массиву.
2. Неправильное описание достаточно больших массивов.
3. Неправильный порядок следования индексов.
Ошибки арифметических операций (см. также Ошибки в описания переменных)
1. Неверное указание типа переменной (например, целочисленной вместо действительной).
2. Переполнение и потеря значимости.
3. Использование неверных констант.
4. Неверное определение порядка действий.
5. Деление на нуль.
6. Извлечение квадратного корня из отрицательного числа.
7. Потеря значащих разрядов числа.
Ошибки в подпрограммах
1. Неправильное описание функции.
2. Неправильное указание требуемых параметров подпрограммы.
3. Неверное число параметров.
4. Неверные значения параметров.
Ошибки ввода-вывода (см. также Ошибки при работе с данными)
1. Неправильный выбор спецификаций формата ввода-вывода.
2. Использование записей неправильной длины или неверного формата.
Ошибки в цепочках символов
1. Указание неверной длины цепочки символов.
2. Обращение к символу за пределами строки.
Ошибки логических операций
1. Неправильное применение логического оператора.
2. Сравнение переменных разного типа.
3. Пропуск оператора ELSE в сложных операторах IF, включающих множество условий.
Ошибки в применении разделителей
1. Отсутствие признака конца оператора.
2. Отсутствие признака окончания комментария.
3. Использование открывающих кавычек вместо закрывающих и наоборот.
4. Несогласованность кавычек в пределах строки.
5. Преждевременное появление символа признака конца.
Прочие ошибки
1. Неправильное использование полей операторов.
2. Использование неподходящей функции.
ОШИБКИ СПЕЦИАЛЬНОГО ВИДА
Семантические ошибки
Вызываются неглубоким пониманием действия той или иной команды, например убежденностью в том, что результаты арифметических операций округляются. Другим примером подобных ошибок может служить неправильное предположение, что цикл не будет выполняться, если конечное значение переменной цикла меньше начального.
Ошибки в синхронизации операций
Такие ошибки возникают в тех случаях, когда две операции зависят, друг от друга по времени, т.е. операция В не может начаться, пока не будет завершена операция А. Если же операция В начинается преждевременно, то возможно появление ошибок синхронизации. Ошибки этого типа называются ситуационными.
Ошибки с восстановлением
Эти ошибки имеют место при отказах оборудования или системного программного обеспечения. Термин «ошибки с восстановлением» подчеркивает, что в случае нарушения нормального функционирования системы по той или иной причине (исчезновение питающего напряжения, поломка диска и т.п.) нежелательно полное разрушение или частичное повреждение файлов.
Ошибки, связанные с перегрузкой системы
Ошибки подобного рода имеют место лишь тогда, когда превышается объем внутренних таблиц, буферных накопителей или прочих участков памяти. Эти ошибки губительно действуют на системы, работающие в режиме реального времени, но могут не проявляться годами, пока не создастся соответствующая ситуация.
1.14 Средства отладки
Разнообразие отладочных средств является залогом успеха при отладке программ. Однако программисту редко удается обойтись, стандартными средствами отладки и избежать создания своих собственных средств.
Существует несколько типов отладочных средств, применявших при программировании:
1. Распечатывание содержимого памяти.
2. Отслеживание хода выполнения алгоритма.
3. Отслеживание обращений к переменным.
4. Отслеживание обращений к подпрограммам.
5. Проверка индексов.
6. Воспроизведение значений переменных.
Вывод содержимого памяти на печать предполагает регистрацию текущего состояния программы в некоторый момент ее выполнения. Обычно такая распечатка осуществляется на машинном языке и по целому ряду причин имеет ограниченное применение. Главная из этих причин - трудность сравнения распечатки с исходной программой, поскольку от программиста требуется понимание машинного языка и умение сопоставлять записи на этом языке с записями на языке высокого уровня. В том случае, если компилятор оптимизирует исходную программу, дело еще более осложняется, даже, несмотря на знание программистом машинного языка. Компиляторы с высокой степенью оптимизации могут производить настолько серьезные перегруппировки операторов внутри программы, что распечатка ее на машинном языке почти не приносит пользы. Поскольку информация, содержащаяся в распечатке, дается не в той форме, которая нужна для ее практического использования, наблюдается тенденция к созданию отладочных средств, которые выдают отладочную информацию в более удобном виде.
Отслеживание хода выполнения алгоритма представляет собой регистрацию логического пути выполнения программы. Она может быть использована для проверки правильности выполнения последовательности операций, заданной программистом, и текущих значений переменных. Обычно различают три вида такого слежения
для контроля передач управления в программе, для контроля значении переменных и для регистрации вызовов подпрограмм. В первом случае на печать выдаются метки выполняемых операторов, во втором случае - метки изменяющихся переменных и их новые значения. Третий вид слежения оказывается особенно полезным при отладке программ, в которых имеется много обращений к подпрограммам. При каждом обращении выдается на печать имя подпрограммы, а при выходе из нее - сообщение о возврате в основную программу.
Средства отслеживания обращений к переменным разрабатываются с таким расчетом, чтобы печатались не все переменные подряд, а только указанные в конкретном списке.
Проверка индексов предназначена для контроля за правильностью индексации именованных массивов посредством сопоставления их индексов с объявленными границами массива. Если границы оказываются нарушенными, печатается сообщение об ошибке. Обычно имеется возможность контроля, как всех массивов, так и заданного их множества.
1.15 Автоматические проверки
При отладке следует широко использовать всевозможные проверки, выполняемые компьютером автоматически. К ним относятся контроль деления на нуль, арифметического переполнения, арифметической потери значимости, длины цепочек символов и значений индексов. В некоторых компиляторах предусматривается возможность включения и отключения этих средств контроля в связи со значительными затратами машинного времени на указанные проверки. Средства такого контроля наряду с обнаружением упомянутых специфических ошибок часто способны выявлять и серьезные логические ошибки.
1.16 Программирование без ошибок
Если вы верите, что можете писать программы правильно, так оно и будет. Если же вы убеждены, что написанная вами программа непременно содержит ошибки, - они неизбежны. Многие программисты считают непреложной истиной, что их программа обязательно будет испещрена ошибками и что половину их рабочего времени займет отладка. Не сомневайтесь, так оно и будет.
В то же время, если вы ощущаете, что способны писать программу без ошибок с самого начала, вас не будет подводить небрежность, оправдываемая предвзятым мнением, и вы сможете сосредоточиться на исключении всех ошибок еще до первого цикла компилирования программы. Ниже приводится целый ряд полезных рекомендаций, направленных на создание программ без ошибок.
Прежде всего, после написания части программы сразу проверяйте ее. Если вы ни разу не попытаетесь ее откомпилировать, вслед за этим на компьютере законченный блок программы, то не будет никаких оснований надеяться на то, что в дальнейшем программа окажется работоспособной. И неудивительно если потом вы обнаружите целый ряд опечаток или логических ошибок и будете вынуждены подвергать программу многократным испытаниям, пока в ней не исчезнут все явные ошибки.
Иногда внимательное прочтение программы до начала работы с ней может избавить вас от необходимости выполнения нескольких отладочных прогонов, однако добровольное признание за собой права на большое количество ошибок зачастую просто парализует вашу способность писать программы правильно. Ведь если вы ожидаете, что программа будет содержать ошибки, вы даже не будете пытаться сделать ее правильной с самого начала.
В этом отношении полезны следующие рекомендации:
1. Добивайтесь правильности работы логических узлов программы посредством последовательного продвижения по блок-схеме алгоритма сверху вниз, пошагового уточнения и попутной проверки.
2. Старайтесь с самого начала избегать синтаксических ошибок. Разумеется, вы знакомы с подавляющим большинством синтаксических конструкций используемого языка программирования, однако, если возникает хоть какое-то сомнение, обратитесь, вновь к синтаксическим правилам, подобно тому, как вы проверяете написание слова по словарю.
3. Не допускайте опечаток. Следите за печатаемым текстом и по окончании сделаете еще одну компиляцию. Многие виды опечаток не обнаруживаются компилятором и потому превращаются впоследствии в ошибки.
Если вы будете строго следовать этим трем советам и концентрировать свое внимание на выполняемой работе, вы сразу заметите, что стали программировать на порядок лучше.
Делайте программу правильной с самого начала.
Изучение практики программирования показало, что многие-программисты тратят на отладку половину своего времени, Следовательно, отладка - процесс весьма дорогостоящий, и надо стремиться сразу, писать правильные программы, чтобы не возникало необходимости в их отладке. И в этом вопросе не допустить проникновения ошибок в программу.
Если в нашем распоряжении находится программа, в которой при тестировании обнаружено и исправлено 10 ошибок, и программа, в которой в результате тестирования не выявлено ни одной ошибки, то мы склоны в большей степени полагаться на последнюю программу. Поэтому лучший путь к сохранению уверенности в хорошем качестве программы - это недопущение в ней ошибок.
1.17 Предотвращение ошибок
Обычно с отладкой связана наибольшая часть затрат по разработке программы, поэтому необходимо стремиться к предупреждению программных ошибок. Некоторые из них можно избежать, если руководствоваться приводимыми ниже правилами.
Не применяйте непроверенных способов программирования. Имейте в виду, что любое новое средство можно считать эффективным лишь тогда, когда имеется твердая уверенность в том, что оно нормально работает. Используйте простейшие операторы. Не пытайтесь обхитрить компилятор или операционную систему. Они настолько сложны, что бывает необыкновенно трудно найти в них такое место, где можно нарушить синтаксические правила и все же продолжать получать верные результаты. Однако если даже предположить, что это удалось сделать, остается нерешенной другая проблема: как гарантировать работоспособность «хитроумной» программы в условиях новых версий или изменений машинного языка и операционной системы? Ведь изготовитель ЭВМ совсем не обязан над этим задумываться, а обнаружить старую ошибку в новых условиях чрезвычайно трудно, так как со времени написания программы может пройти 1-2 года.
Старайтесь не использовать принцип умолчания. Во всех языках программирования имеются некоторые стандартные значения переменных, которые компилятор присваивает им по умолчанию. Это экономит трудозатраты программиста, но чревато опасностями, потому что фирмы-изготовители время от времени изменяют систему умолчаний. Программист же при этом может предположить, что он неверно использовал оператор умолчания. Известен, случай, когда фирма IBM, для которой характерно частое усовершенствование собственных языков программирования, в очередной обновленной версии языка ПЛ/1 изменила стандартную длину параметра для одного типа переменных. В результате такого изменения многие программы, написанные на этом языке, оказались неработоспособными. Следует отметить также, что механизм действия операторов умолчания в разных машинах различен. Поэтому, если желательно обеспечить независимость программы от конкретной ЭВМ, то лучше избегать излишне частого использования операторов умолчания.
Никогда не допускайте зависимости работы программы от достоверности данных. Не следует полагаться на то, что информация, используемая программой, всегда будет вводиться в нужном виде или в заданных пределах изменения. Необходимо организовывать контроль данных при вводе для того, чтобы убедиться в их правильности. Данные всегда ведут себя в полном соответствии с законом Мэрфи, который гласит: «Все, что может испортиться, портится». Ошибки в них могут вызываться нарушением инструкций по вводу данных, опечатками при подготовке либо сбоями устройств ввода-вывода. Если такого контроля не проводить, то программа будет периодически самым таинственным образом приходить в неработоспособное состояние. И хотя после тщательного анализа ошибки будет показано, что она вызвана входными данными, и программа, и программист прослывут сомнительными.
Добивайтесь полноты логических решений. Если некоторый элемент данных должен принимать значения, равные 1 или 2, не следует после несравнения его с единицей полагать, что значение должно быть равно двум. Подобная практика не позволяет предусмотреть действия программы в ситуациях с неверными данными, которые не так уж редки. Поэтому логика контроля должна быть несколько иной. Вначале надо сравнивать проверяемое значение с единицей, а в случае их неравенства - с двойкой. Однако должна приниматься во внимание и такая ситуация, когда значения не совпадают и во второй раз; на этот случай должны быть запрограммированы соответствующие действия: выдача сообщения об ошибке или аварийный останов. Таким образом, при наличии N возможных условий в программе необходимо выполнять N+1 проверок, из них N рабочих и одну, направленную на выявление ошибки в данных.
Основная концепция процесса отладки заключается в том, чтобы обеспечить выдачу на печать такого объема информации, который позволил бы легко обнаружить программную ошибку. Опытный программист знает при этом, куда надо вставлять отладочные операторы при программировании; начинающий же просто не задумывается об этом на стадии написания программы и потому тратит в последствии на отладку существенную часть своего личного и машинного времени. Между тем редкая программа не нуждается в применении отладочных операторов.
Очень удачно выражена эта мысль у Грюенбергера, который пишет: «Когда отладка завершена, это означает, что программа, несомненно, решает какую-то задачу».
2. Тестирование программ
Если тестирование программы проводится интуитивно, по принципу невмешательства в работу программы и без какого-либо четкого плана испытаний, то этот процесс можно назвать искусством. Если же тестированию предшествует тщательный подбор данных для контрольных примеров и заблаговременный выбор элементом программы, подлежащий проверке, а само оно выполняется последовательно и аккуратно, то тестирование становится наукой.
Разработка алгоритмов и программирование стали ремеслом, которым можно овладеть. Теперь пришло время сделать то же самое в отношении тестирования программ, покончив с подходом к нему как к искусству. Это позволит исключить повторения испытаний, обеспечивать контроль за их эффективным проведением и четко определять момент завершения тестирования.
Испытания любой системы всегда представляют собой один из наиболее ответственных этапов ее разработки и часто бывают связаны с наибольшими трудностями и наибольшим потерями времени. Отладка и тестирование-это два четко различных и непохожих друг на друга этапа. В первом случае происходит устранение синтаксических ошибок и явных ошибок кодирования. Во втором случае имеют дело с программой, не содержащей отмеченных ошибок, которая выдает какие-то правильные результаты. Основная цель выделения отладки и тестирования как отдельных этапов создания программы заключается в том, чтобы обратить внимание на обязательность обеих стадий и необходимость специального планирования временных затрат по каждой из них в отдельности.
Никогда не делайте вывода, что программа правильна, лишь на том основании что, она не отвергнута компилятором, полностью транслирована и выдала численные результаты. Ведь все, что достигнуто в данном случае, - это получение некой выходной информации, не обязательно правильной. В программе все еще может оставаться большое количество логических ошибок, а между тем задача, которая ставится при написании программы, - это не просто получение ответов, но получение правильных ответов. Поэтому обычно бывает, необходима «ручная» проверка результатов. После того как отладка полностью завершена, даже в программе опытного программиста существует примерно одна ошибка на 20-30 написанных операторов. Эти ошибки могут быть как катастрофическими по своим последствиям, так и не значительными и могут быть связаны как с неправильным алгоритмом, так и с несущественными ошибками кодирования. Таким, образом, отлаженная программа - это программа, для которой просто не нашлось подходящего набора тестовых данных, чтобы привести ее к отказу.
2.1 Общие рекомендации
Наиболее важный принцип, относящийся к тестированию программ, состоит в том, чтобы думать об этой стадии еще на этапе написания программы. Следует постоянно задаваться вопросом: как будет тестироваться данный сегмент? Если ответ на вопрос о способе тестирования программы неясен, она должна быть либо переписана заново, либо разбита на модули. Нарушение этого принципа неизбежно приводит к тому, что программу вообще не удается проверить до конца и рано или поздно при очередном компилировании она откажет.
Подобные документы
Тестирование как составляющая часть процесса отладки программного обеспечения, его роль для обеспечения качества продукта. Обнаружение ошибок в программах, выявление причин их возникновения. Подходы к формулированию критериев полноты тестирования.
курсовая работа [1,6 M], добавлен 20.12.2012Стадии разработки программного средства. Средства, методологии и методы его разработки. Оценка надежности и качества проекта. Обоснование необходимости разработки программы. Тестирование как процесс выполнения тестовой программы с намерением найти ошибки.
презентация [57,0 K], добавлен 27.12.2013Угрозы безопасности программного обеспечения и классификация средств атаки на средства защиты ПО. Методы и средства защиты программ от компьютерных вирусов и средств исследования программ. Анализ стандартов в области информационной безопасности.
дипломная работа [1,4 M], добавлен 29.06.2012Реализация программного средства "Действия над матрицами". Разработка кода программного продукта на основе готовой спецификации на уровне модуля. Использование инструментальных средств на этапе отладки программного модуля. Выбор стратегии тестирования.
отчет по практике [296,1 K], добавлен 19.04.2015Обзор существующих моделей параллельного программирования, основные средства отладки эффективности MPI-программ, общие проблемы всех средств трассировки. Создание экспериментальной системы отладки эффективности MPI-программ, этапы работы анализатора.
дипломная работа [767,2 K], добавлен 14.10.2010Сравнительный анализ технологий тестирования. Разработка программного модуля "Интеллектуальная обучающая система для широкого перечня курсов". Обоснование необходимости и важности этапа отладки в процессе разработки данного программного обеспечения.
дипломная работа [101,2 K], добавлен 17.06.2011Изучение различных видов тестирования программного обеспечения. Выявление в программной системе скрытых дефектов до того, как она будет сдана заказчику. Тестирование методом черного ящика. Требования, предъявляемые к процессу тестирования больших систем.
курсовая работа [3,0 M], добавлен 19.11.2009Принципы и алгоритмы обработки прерываний. Набор действий по реализации этапов обработки прерываний микропроцессора. Разработка структуры и алгоритма резидентной программы. Реализация программы на языке Ассемблер, методы её отладки и тестирования.
курсовая работа [348,7 K], добавлен 22.12.2014Изучение составляющих этапов разработки программ, процесса их тестирования, отладки и документирования в контексте курса обучения начинающих программистов. Теоретический анализ постановки задачи и модели программы, создания текста, семантической отладки.
курсовая работа [29,2 K], добавлен 28.11.2010Тестирование как процесс выполнения программы с намерением найти ошибки. Шаги программы при тестировании, его оценка и значение. Роль информационных потоков тестирования, оценивания и отладки. Особенности структурного и функционального тестирования.
презентация [574,8 K], добавлен 22.03.2014