Главная Случайная страница


Полезное:

Как сделать разговор полезным и приятным Как сделать объемную звезду своими руками Как сделать то, что делать не хочется? Как сделать погремушку Как сделать так чтобы женщины сами знакомились с вами Как сделать идею коммерческой Как сделать хорошую растяжку ног? Как сделать наш разум здоровым? Как сделать, чтобы люди обманывали меньше Вопрос 4. Как сделать так, чтобы вас уважали и ценили? Как сделать лучше себе и другим людям Как сделать свидание интересным?


Категории:

АрхитектураАстрономияБиологияГеографияГеологияИнформатикаИскусствоИсторияКулинарияКультураМаркетингМатематикаМедицинаМенеджментОхрана трудаПравоПроизводствоПсихологияРелигияСоциологияСпортТехникаФизикаФилософияХимияЭкологияЭкономикаЭлектроника






Тестирование — процесс творческий.





Вполне вероятно, что для тестирования большой программы требуется больший творческий потенциал, чем для ее проектирования. Выше было показано, что нельзя дать гарантию построения теста, обнаруживающего все ошибки. В дальнейшем будут обсуждаться методы построения хороших наборов тестов, но применение этих методов должно быть творческим.

 

3. Классификация ошибок.

Для классификации ошибок мы должны определить термин «ошибка». Ошибка – это расхождение между вычисленным, наблюдаемым и истинным, заданным или теоретически правильным значением.

Такое определение понятия «ошибка» не является универсальным, так как оно больше подходит для понятия «программная ошибка». В технологии программирования существуют не только программные ошибки, но и ошибки, связанные с созданием программного продукта, например, ошибки в документации программы. Отличие программы и программного продукта достаточно четко определены. Но нас пока будут интересовать программные ошибки.

Итак, по времени появления ошибки можно разделить на три вида:

структурные ошибки набора;

ошибки компиляции;

ошибки периода выполнения.

1 Пандора – в древнегреческой мифологии девушка, созданная из земли и воды богом огня и кузнечного ремесла Гефестом. Она получила от верховного бога Зевса ящик со всеми человеческими несчастьями, которые случайно выпустила, приоткрыв из любопытства крышку; отсюда «ящик Пандоры» – источник всяческих бедствий.

Структурные ошибки возникают непосредственно при наборе программы. Что это за ошибки? Если кто-то работал в среде разработки Microsoft Visual Basic, то он знает, что если набрать оператор If, затем сравнение и нажать на клавишу Enter, не набрав слова Then, то Visual Basic укажет, что возникла ошибка компиляции. Это не совсем верно, так как компиляция в Visual Basic происходит только непосредственно при вы полнении команды программы. В данном случае мы имеем дело именно со структурной ошибкой набора.

Данный тип ошибок определяется либо при наборе программы (самой IDE (I ntegrated D evelopment E nvironment) – интегрированной средой разработки) или при ее компиляции, если среда не разделяет первые два типа ошибок.

К данному типу ошибок относятся такие как: несоответствие числа открывающих скобок числу закрывающих, отсутствие парного оператора (например, try без catch), неправильное употребление синтаксических знаков и т. п.

Во многих средах разработки программного обеспечения данный тип ошибок объединяется со следующим типом, так как раннее определение ошибок вызывает некоторое неудобство при наборе программ (скажем, я задумал что-то написать, а потом вспомнил, что в начале пропустил оператор, тогда среда разработки может выдать мне ошибку при попытке перейти в другую строку).

Еще раз нужно отметить, что данный тип ошибок достаточно уникален и выделяется в отдельный тип только некоторыми средами разработки программного обеспечения.

Ошибки компиляции возникают из-за ошибок в тексте кода. Они включают ошибки в синтаксисе, неверное использование конструкций языка (оператор else в операторе for и т. п.), использование несуществующих объектов или свойств, методов у объектов.

Среда разработки (компилятор) обнаружит эти ошибки при общей компиляции приложения и сообщит о последствиях этих ошибок. Необходимо подчеркнуть слово «последствия» – это очень важно. Дело в том, что часто, говоря об ошибках, мы не разделяем проявление ошибки и саму ошибку, хотя это и не одно и то же. Например, ошибка «неопределенный класс» не означает, что класс не определен. Он может быть не подключенным, так как не подключен пакет классов.

Ошибки периода выполнения возникают, когда программа выполняется и компилятор (или операционная система, виртуальная машина) обнаруживает, что оператор делает попытку выполнить недопустимое или невозможное действие. Например, деление на ноль. Предположим, имеется такое выражение:

ratio = firstValue / sum.

Если переменная sum содержит ноль, то деление – недопустимая операция, хотя сам оператор синтаксически правилен. Прежде, чем программа обнаружит эту ошибку, ее необходимо запустить на выполнение.

Хотя данный тип ошибок называется «ошибками периода выполнения», это не означает, что ошибки находятся только после запуска программы. Вы можете выполнять программу в уме и обнаружить ошибки данного типа, однако, понятно, что это крайне неэффективно.

Если проанализировать все типы ошибок согласно первой классификации, то можно прийти к заключению, что при тестировании приходится иметь дело с ошибками периода выполнения, так как первые два типа ошибок определяются на этапе кодирования.

В теоретической информатике программные ошибки классифицируют по степени нарушения логики на:

синтаксические;

семантические;

прагматические.

Синтаксические ошибки заключаются в нарушении правописания или пунктуации в записи выражений, операторов и т. п., т. е. в нарушении грамматических правил языка. В качестве примеров синтаксических ошибок можно назвать:

• пропуск необходимого знака пунктуации;

• несогласованность скобок;

• пропуск нужных скобок;

• неверное написание зарезервированных слов;

• отсутствие описания массива.

Все ошибки данного типа обнаруживаются компилятором.

Семантические ошибки заключаются в нарушении порядка операторов, параметров функций и употреблении выражений. Например, параметры у функции add (на языке Java) в следующем выражении указаны в неправильном порядке: GregorianCalendar.add(1, Calendar.MONTH).

Параметр, указывающий изменяемое поле (в примере – месяц), должен идти первым. Семантические ошибки также обнаруживаются компилятором.

Надо отметить, что некоторые исследователи относят семантические ошибки к следующей группе ошибок.

Прагматические ошибки (или логические) заключаются в неправильной логике алгоритма, нарушении смысла вычислений и т. п. Они являются самыми сложными и крайне трудно обнаруживаются. Компилятор может выявить только следствие прагматической ошибки (см. выше пример с делением на ноль, компилятор обнаружит деление на ноль, но когда и почему переменная sum стала равна нулю – должен найти программист).

Таким образом, после рассмотрения двух классификаций ошибок можно прийти к выводу, что на этапе тестирования ищутся прагматические ошибки периода выполнения, так как остальные выявляются в процессе программирования.

На этом можно было бы закончить рассмотрение классификаций, но с течением времени накапливался опыт обнаружения ошибок и сами ошибки, некоторые из которых образуют характерные группы, которые могут тоже служить характерной классификацией.

Ошибка адресации – ошибка, состоящая в неправильной адресации

данных (например, выход за пределы участка памяти).

Ошибка ввода-вывода – ошибка, возникающая в процессе обмена

данными между устройствами памяти, внешними устройствами.

Ошибка вычисления – ошибка, возникающая при выполнении

арифметических операций (например, разнотипные данные, деление на

нуль и др.).

Ошибка интерфейса – программная ошибка, вызванная несовпадением характеристик фактических и формальных параметров (как правило, семантическая ошибка периода компиляции, но может быть и логической ошибкой периода выполнения).

Ошибка обращения к данным – ошибка, возникающая при обращении программы к данным (например, выход индекса за пределы массива, не инициализированные значения переменных и др.).

Ошибка описания данных – ошибка, допущенная в ходе описания

данных.

 

4. Первичное выявление ошибок.

В течение многих лет большинство программистов убеждено в том, что программы пишутся исключительно для выполнения их на машине и не предназначены для чтения человеком, а единственным способом тестирования программы является ее исполнение на ЭВМ. Это мнение стало изменяться в начале 70-х годов в значительной степени благодаря книге Вейнберга «Психология программирования для ЭВМ» [9]. Вейнберг по казал, что программы должны быть удобочитаемыми и что их просмотр должен быть эффективным процессом обнаружения ошибок.

По этой причине, прежде чем перейти к обсуждению традиционных методов тестирования, основанных на применении ЭВМ, рассмотрим процесс тестирования без применения ЭВМ («ручное тестирование»), являющийся по сути первичным обнаружением ошибок. Эксперименты показали, что методы ручного тестирования достаточно эффективны с точки зрения нахождения ошибок, так что один или несколько из них должны использоваться в каждом программном проекте. Описанные здесь методы предназначены для периода разработки, когда программа закодирована, но тестирование на ЭВМ еще не началось. Аналогичные методы могут быть получены и применены на более ранних этапах процесса создания программ (т. е. в конце каждого этапа проектирования). Следует заметить, что из-за неформальной природы методов ручного тестирования (неформальной с точки зрения других, более формальных методов, таких, как математическое доказательство корректности программ) первой реакцией часто является скептицизм, ощущение того, что простые и неформальные методы не могут быть полезными. Однако их использование показало, что они не «уводят в сторону». Скорее эти методы способствуют существенному увеличению производительности и повышению надежности программы. Во-первых, они обычно позволяют раньше обнаружить ошибки, уменьшить стоимость исправления последних и увеличить вероятность того, что корректировка произведена правильно. Во-вторых, психология программистов, по-видимому, изменяется, когда начинается тестирование на ЭВМ. Возрастает внутреннее напряжение и появляется тенденция «исправлять ошибки так быстро, как только это возможно». В результате программисты допускают больше промахов при корректировке ошибок, уже найденных во время тестирования на ЭВМ, чем при корректировке ошибок, найденных на более ранних этапах.

Кроме того, скептицизм связан с тем, что это «первобытный метод».

 

5. Список вопросов для выявления ошибок при инспекции.

Важной частью процесса инспектирования является проверка программы на наличие общих ошибок с помощью списка вопросов для выявления ошибок. Концентрация внимания в предлагаемом списке на рассмотрении стиля, а не ошибок (вопросы типа «Являются ли комментарии точными и информативными?» и «Располагаются ли символы THEN/ELSE и DO/END по одной вертикали друг под другом?») представляется неудачной, так же как и наличие неопределенности в списке, уменьшающее его полезность (вопросы типа «Соответствует ли текст программы требованиям, выдвигаемым при проектировании?»). Список, приведенный в данном разделе, был составлен различными авторами. За основу взят список Майерса и дополнен автором после многолетнего изучения ошибок программного обеспечения, разработанного как лично, так и другими специалистами, а также учебных программ. В значительной мере он является независимым от языка; это означает, что большинство ошибок встречается в любом языке программирования. Любой специалист может дополнить этот список вопросами, позволяющими выявить ошибки, специфичные для того языка программирования, который он использует, и обнаруженные им в результате выполнения процесса инспектирования.

 

6. Ошибки обращения к данным.

Сводный список вопросов таков:

1. Используются ли переменные с неустановленными значениями? Наличие переменных с неустановленными значениями – наиболее часто встречающаяся программная ошибка, она возникает при различных обстоятельствах. Для каждого обращения к единице данных (например, к переменной, элементу массива, полю в структуре, атрибуту в классе) попытайтесь неформально «доказать», что ей присвоено значение в проверяемой точке.

2. Лежат ли индексы вне заданных границ? Не выходит ли значение каждого из индексов за границы, определенные для соответствующего измерения при всех обращениях к массиву, вектору, списку и т. п.?

3. Есть ли нецелые индексы?

Принимает ли каждый индекс целые значения при всех обращениях к массиву, вектору, списку? Нецелые индексы не обязательно являются ошибкой для всех языков программирования, но представляют практическую опасность.

4. Есть ли «подвешенные» обращения?

Создан ли объект (выделена ли память) для всех обращений с помощью указателей или переменных-ссылок на объект (или память)? Наличие, переменных-ссылок представляет собой ошибку типа «подвешенного обращения». Она возникает в ситуациях, когда время жизни указателя больше, чем время жизни объекта/памяти, к которому/ой производится обращение. Например, к такому результату приводит ситуация, когда указатель задает локальную переменную в теле метода, значение указателя присваивается выходному параметру или глобальной переменной, метод завершается (освобождая адресуемую память), а программа затем пытается использовать значение указателя. Как и при поиске ошибок первых трех типов, попытайтесь неформально доказать, что для каждого обращения, использующего переменную-указатель, адресуемая память/объект существует. Этот тип ошибок характерен для языка Си или С++, где широко используются ссылки и указатели. Язык Java в этом отношении более развит, например, при потере всех ссылок на объект, объект переходит в «кучу мусора», где автоматически освобождается память из-под объекта (объект удаляется) специальным сборщиком мусора. Последние изменения в языке С++, выполненные командой разработчиков Microsoft, которые преобразовали этот язык в С#, реализуют похожий механизм.

5. Соответствуют ли друг другу определения структуры и ее использование в различных методах?

Если к структуре данных обращаются из нескольких методов или процедур, то определена ли эта структура одинаково в каждой процедуре и используется ли она корректным способом?

6. Превышены ли границы строки?

Не превышены ли границы строки при индексации в ней? Существуют ли какие-нибудь другие ошибки в операциях с индексацией или при обращении к массивам по индексу?

 

 

7. Ошибки описания данных

Сводный список вопросов таков:

1. Все ли переменные описаны?

Все ли переменные описаны явно? Отсутствие явного описания не обязательно является ошибкой (например, Visual Basic допускает отсутствие описания), но служит потенциальным источником беспокойства. Так, если в подпрограмме на Visual Basic используется элемент массива и отсутствует его описание (например, в операторе DIM), то обращение к массиву может вызвать ошибку (например, Х = А(12)), так как по умолчанию, массив определен только на 10 элементов. Если отсутствует явное описание переменной во внутренней процедуре или блоке, следует ли понимать это так, что описание данной переменной совпадает с описанием во внешнем блоке? При разработке больших программных изделий неявное описание данных (описание данных по умолчанию) зачастую запрещают методически (если это не запрещено языком), чтобы упростить поиск ошибок при комплексной отладке.

2. Правильно ли инициализированы объекты, массивы и строки?

Если начальные значения присваиваются переменным в операторах описания, то правильно ли инициализируются эти значения? Правильно ли создаются объекты, используется ли соответствующий конструктор?

3. Понятны ли имена переменных?

Наличие переменных с бессмысленными именами (например, i и j) не является ошибкой, но является объектом пристального внимания. Классически i и j являются цикловыми переменными, а вот названий типа t125 следует избегать, так как возможна путаница имен.

4. Нельзя ли обойтись без переменных со сходными именами?

Есть ли переменные со сходными именами (например, user и user)? Наличие сходных имен не обязательно является ошибкой, но служит признаком того, что имена могут быть перепутаны где-нибудь внутри программы.

5. Корректно ли произведено описание класса?

Правильно ли происходит описание атрибутов и методов класса? Имеются ли методы или атрибуты, которые по смыслу не подходят к данному классу? Не является ли класс громоздким? Наличие положительных ответов на эти вопросы указывает на возможные ошибки в анализе и проектировании системы.

8. Ошибки вычислений

Сводный список вопросов таков:

1. Производятся ли вычисления с использованием данных разного типа?

Существуют ли вычисления, использующие данные разного типа? Например, сложение переменной с плавающей точкой и целой переменной. Такие случаи не обязательно являются ошибочными, но они должны быть тщательно проверены для обеспечения гарантии того, что правила преобразования, принятые в языке, понятны. Это важно как для языков с сильной типизацией (например, Ada, Java), так и для языков со слабой типизацией (например, С++, хотя он тяготеет к сильной типизации). Например, для языка Java код

byte a, b, c;

c = a + b;

может вызвать ошибку, так как операция «сложение» преобразует данные к типу int, и результат может превысить максимально возможное значение для типа byte. Таким образо, важным для вычислений с использованием различных типов данных является явное или неявное преобразование типов. Ошибки, связанные с использованием данных разных типов являются одними из самых распространенных.

2. Производятся ли вычисления неарифметических переменных?

3. Возможно ли переполнение или потеря промежуточного результата

при вычислении?

Это означает, что конечный результат может казаться правильным, но промежуточный результат может быть слишком большим или слишком малым для машинного представления данных. Ошибки могут возникнуть даже если существует преобразование типов данных.

4. Есть ли деление на ноль?

Классическая ошибка. Требует проверки всех делителей на не равенство нулю. Следствием данной ошибки является либо сообщение «деление на ноль», либо «переполнение», если делитель очень близок к нулю, а результат не может быть сохранен в типе частного (превышает его).

5. Существуют ли неточности при работе с двоичными числами?

6. Не выходит ли значение переменной за пределы установленного диапазона?

Может ли значение переменной выходить за пределы установленного для нее логического диапазона? Например, для операторов, присваивающих значение переменной probability (вероятность), может быть произведена проверка, будет ли полученное значение всегда положительным и не превышающим единицу. Другие диапазоны могут зависеть от области решаемых задач.

7. Правильно ли осуществляется деление целых чисел?

Встречается ли неверное использование целой арифметики, особенно деления? Например, если i – целая величина, то выражение 2*i/2 = i зависит от того, является значение i четным или нечетным, и от того, какое действие – умножение или деление – выполняется первым.

 

 

9. Ошибки при сравнениях

Сводный список вопросов таков:

1. Сравниваются ли величины несовместимых типов? Например, число со строкой.

2. Сравниваются ли величины различных типов?

Например, переменная типа int с переменной типа long? Каждый язык ведет себя в этих случаях по-своему, проверьте это по его описанию. Как выполняются преобразования типов в этих случаях?

3. Корректны ли отношения сравнения?

Иногда возникает путаница понятий «наибольший», «наименьший», «больше чем», «меньше чем».

4. Корректны ли булевские выражения?

Если выражения очень сложные, имеет смысл преобразовать их или проверять обратное утверждение.

5. Понятен ли порядок следования операторов?

Верны ли предположения о порядке оценки и следовании операторов для выражений, содержащих более одного булевского оператора? Иными словами, если задано выражение (А == 2) &&(В == 2) || (С == 3), понятно ли, какая из операций выполняется первой: И или ИЛИ?

6. Понятна ли процедура разбора компилятором булевских выражений?

Влияет ли на результат выполнения программы способ, которым конкретный компилятор выполняет булевские выражения? Например, оператор if ((x!= 0) && ((y/x) > z)) является приемлемым для Java (т. е. компилятор заканчивает проверку, как & только одно из выражений в операции И окажется ложным), но это выражение может привести к делению на ноль при использовании компиляторов других языков.

10. Ошибки в передачах управления.

Сводный список вопросов таков:

1. Может ли значение индекса в переключателе превысить число переходов? Например, значение переключателя для оператора select case.

2. Будет ли завершен каждый цикл?

Будет ли каждый цикл, в конце концов, завершен? Придумайте неформальное доказательство или аргументы, подтверждающие их завершение. Хотя иногда бесконечные циклы не являются ошибкой, но лучше их избегать.

3. Будет ли завершена программа? Будет ли программа, метод, модуль или подпрограмма в конечном счете завершена?

4. Существует ли какой-нибудь цикл, который не выполняется из-за входных условий?

Возможно ли, что из-за входных условий цикл никогда не сможет выполняться? Если это так, то является ли это оплошностью?

5. Есть ли ошибки отклонения числа итераций от нормы?

Существуют ли какие-нибудь ошибки «отклонения от нормы» (например, слишком большое или слишком малое число итераций)?

 

 

11. Ошибки интерфейса

Сводный список вопросов таков:

1. Равно ли число входных параметров числу аргументов?

Равно ли число параметров, получаемых рассматриваемым методом, числу аргументов, ему передаваемых каждым вызывающим методом? Правилен ли порядок их следования? Первый тип ошибок может обнаруживаться компилятором (но не для каждого языка), а вот правильность следования (особенно, если параметры одинакового типа) является важным моментом.

2. Соответствуют ли единицы измерения параметров и аргументов?

Например, нет ли случаев, когда значение параметра выражено в градусах, а аргумента – в радианах? Или ошибки связанные с размерностью параметра/аргумента (например, вместо тонн передаются килограммы).

3. Не изменяет ли метод аргументы, являющиеся только входными?

4. Согласуются ли определения глобальных переменных во всех использующих их методах?

 

 

Выводы

Мы рассмотрели несколько решений для автоматизации процесса тестирования (и автоматизированного тестирования). Отметим, что тестирование проектов можно и проводить и без помощи специальных средств(например, редактировать тестовые случаи в блокноте, а тест - сьюиты хранить в папках). Но это неудобно для тестирования больших проектов, при работе а команде более двух человек.

Все рассмотренные продукты предназначены для тестирования функциональности(регрессионное тестирование, тестирование нового функционала), так же выполняют коммуникативную функию(тестировщик - разработчик).

Так же решения, такие как HP Software предполагают взаимодействие разработчиков и различных тестировщиков обычных, ручных(не автоматических, которые обычно тестируют функционал(регрессионное тестирование, тестирование нового функционала)), автоматизаторов тестирования(разрабатывают автоматизированные скрипты), нагрузочных, тестировщиков и, наконец, самих разработчиков.

 

Date: 2016-11-17; view: 283; Нарушение авторских прав; Помощь в написании работы --> СЮДА...



mydocx.ru - 2015-2024 year. (0.007 sec.) Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав - Пожаловаться на публикацию