Начала_информатики7

Посмотреть архив целиком
Глава 8 Тестирование и отладка
программных продуктов
Введение. Виды контроля качества программного
продукта.
Тестирование – очень важный и трудоемкий этап процесса разработки
программного обеспечения, так как правильное тестирование
позволяет выявить подавляющее большинство ошибок, допущенных
при составлении программ.
Многократные проводимые исследования показали, что чем раньше
обнаруживаются те или иные несоответствия или ошибки, тем
больше вероятность их правильного исправления и ниже его
стоимость.
Современные технологии разработки программного обеспечения
предусматривают раннее обнаружение ошибок за счет выполнения
контроля результатов всех этапов и стадий разработки. На
начальных этапах такой контроль осуществляется в основном
вручную или с использованием CASE-средств, на последних –
принимает форму тестирования

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

Введение. Виды контроля качества
программного продукта(3)
Процесс разработки программного обеспечения, в том виде, как он
определяется в современной модели жизненного цикла
программного
обеспечения,
предполагает
три
стадии
тестирования:
• автономное тестирование компонент программного обеспечения;
• комплексное тестирование разрабатываемого программного
обеспечения;
• системное или оценочное тестирование на соответствие
основным критериям качества.

Введение. Виды контроля качества
программного продукта(4)
Для повышения качества тестирования рекомендуется соблюдать
следующие основные принципы:
• предполагаемые результаты должны быть известны до
тестирования;
• следует избегать тестирования программы автором;


необходимо досконально изучать результаты каждого теста;



необходимо проверять действия программы на неверных данных;



необходимо проверять программу на неожиданные побочные
эффекты на неверных данных.

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

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

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

8.1 Ручной контроль программного
продукта(2)
Основными методами ручного тестирования являются:
• инспекции исходного текста;
• сквозные просмотры;
• просмотры за столом;
• обзоры программ.

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

8.1 Ручной контроль программного
продукта(3)
Общая процедура инспекции предполагает следующие операции:


участникам группы заранее выдается листинг программы и
спецификация на нее;



программист рассказывает о логике работы программы и отвечает
на вопросы инспекторов;



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

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

8.1 Ручной контроль программного
продукта(4)
Сквозные просмотры
Сквозной просмотр, как и инспекция, представляет собой набор
способов обнаружения ошибок, осуществляемых группой лиц,
просматривающих текст программы.
Группа по выполнению сквозного контроля состоит из 3-5 человек:
председатель или координатор, секретарь, фиксирующий все
ошибки, специалист по тестированию, программист и независимый
эксперт.
Сквозной просмотр предполагает выполнение следующих процедур:
• участникам группы заранее выдают листинг программы и
спецификация на нее;
• участникам заседания предлагают несколько тестов, написанных на
бумаге;
• участники заседания мысленно выполняют каждый тест в
соответствии с логикой программы, при этом состояние программы
(значения переменных) отслеживается на бумаге или доске;

8.1 Ручной контроль программного
продукта(5)


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

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

8.1 Ручной контроль программного
продукта(6)
Оценка посредством просмотра
Этот метод является методом оценки анонимной программы в терминах
ее общего качества, простоты эксплуатации и ясности.
Цель этого метода – обеспечить сравнительно объективную оценку и
самооценку программистов.
Такая оценка выполняется следующим образом. Выбирается
программист-администратор процесса. Администратор набирает
группу от 6 до 20 участников, которые должны заниматься
разработкой сходных программ. Каждому участнику предлагается
представить для рассмотрения две программы с его точки зрения
наилучшую и наихудшую. Отобранные программы случайным
образом распределяются между участниками. Им дают по 4
программы – две наилучшие и две наихудшие, но не говорят, какие
программы плохие, а какие – хорошие. Программист просматривает
эти программы и заполняет анкету, в которой оценивает качество
программ по семибалльной шкале.
После этого результаты оценки сверяют, а проверяющий дает общий
комментарий и рекомендации по улучшению программ.

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

8.2 Структурное тестирование(2)
m

1
да

a>1и b=0
нет

x := x / a

a ? 1или b

?0

да

a=2 или x>1
нет

a>1и b=0

2

3

4
x := x + 1

a ?2иx

a=2 или x>1

?1
5

Return

6

а

б

Схема алгоритма процедуры примера (а) и ее граф передач управления (б)

8.2 Структурное тестирование(3)
Формирование тестовых наборов для тестирования маршрутов может
осуществляться по нескольким критериям. К таким критериям относят:
• покрытие операторов;
• покрытие решений;
• покрытие условий;
• покрытие решений/условий;
• комбинаторное покрытие условий.

Покрытие операторов
Критерий покрытия операторов подразумевает такой подбор тестов, чтобы
каждый оператор программы выполнялся, по крайней мере, один раз.
Это необходимое, но недостаточное условие для приемлемого
тестирования.
Для описанного фрагмента, можно было бы выполнить каждый оператор
один раз, задав в качестве входных данных a=2, b=0, x=3. Но при этом,
из второго условия следует, что переменная х может принимать любое
значение, и в некоторых версиях Паскаля это значение проверяться не
будет (!).

8.2 Структурное тестирование(4)
Покрытие решений (переходов)

Для реализации этого критерия необходимо такое количество и состав
тестов, чтобы результат проверки каждого условия (решение) принимал
значения «истина» или «ложь», по крайней мере, один раз.
Например для алгоритма, которой представлен на рисунке, можно по
методу покрытия решений составить два теста, покрывающие либо
пути: 1–2–4–6, 1–2–3–4–5–6, либо пути: 1–2–3–4–6, 1–2–4–5–6,
например:
a=3, b=0, x=3 – путь 1–2–3–4–5–6;
a=2, b=1, x=1 – путь 1–2–4–6.

Покрытие условий

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

8.2 Структурное тестирование(5)
Программа, алгоритм которой представлен на рисунке, проверяет четыре
условия:
a>1; (1)
b=0; (2)
a=2; (3)
x>1. (4)
Тесты, удовлетворяющие этому условию:
a=2, b=0, x=4 – путь 1–2–3–4–5–6, условия: 1–да, 2–да, 3–да, 4–да;
a=1, b=1, x=1 – путь 1–2–4–6, условия; 1–нет, 2–нет, 3–нет, 4–нет.
Критерий покрытия условий часто удовлетворяет критерию покрытия
решений, но не всегда. Например, тесты для ранее рассмотренного
примера :
a=1, b=0, x=3 – путь 1–2–3–6, условия: 1–нет, 2–да, 3–нет, 4–да;
a=2, b=1, x=1 – путь 1–2–3–4–5–6, условия: 1–да, 2–нет, 3–да, 4–нет
покрывают результаты всех условий, но только два из четырех
результатов решений: не выполняется результат «истина» первого
решения и результат «ложь» второго.
Основной недостаток метода – недостаточная чувствительность к
ошибкам в логических выражениях.

8.2 Структурное тестирование(6)
Покрытие решений/условий
Согласно этому методу тесты должны составляться так, чтобы, по
крайней мере, один раз выполнились все возможные результаты
каждого условия и все результаты каждого решения, и каждому
оператору управление передавалось, по крайней мере, один раз.
Для приведенного примера этому критерию удовлетворяют тесты:
a=2, b=0, x=4 – путь 1–2–3–4–5–6, условия: 1–да, 2–да, 3–да, 4–да;
a=1, b=1, x=1 – путь 1–2–4–6, условия; 1–нет, 2–нет, 3–нет, 4–нет.

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

8.2 Структурное тестирование(7)
Для алгоритма, которой представлен на рисунке, необходимо покрыть
тестами восемь комбинаций:
a>1, b=0; (1)
a=2, x>1; (5)
a>1, b?0; (2)
a=2, x?1; (6)
a?1, b=0; (3)
a?2, x>1; (7)
a?1; b?0; (4)
a?2, x?1. (8)
Эти комбинации можно проверить четырьмя тестами:
a=2, b=0, x=4 – проверяет комбинации 1, 5;
a=2, b=1, x=1 – проверяет комбинации 2, 6;
a=1, b=0, x=2 – проверяет комбинации 3, 7;
a=1, b=1, x=1 – проверяет комбинации 4, 8.
Однако, представленные тесты не покрывают всех путей, например, 1-23-4-6. Поэтому иногда необходима реализация восьми тестов.

8.2 Структурное тестирование(8)
Структурный подход к тестированию имеет ряд недостатков. Так
тестовые наборы, построенные по данной стратегии:
• не обнаруживают пропущенных маршрутов;
• не обнаруживают ошибок, появление которых зависит от
обрабатываемых данных, например, if (a - b)< eps – пропуск функции
abs проявится только, если a < b;
• не дают гарантии, что программа соответствует заданию, например,
если вместо сортировки по убыванию реализована сортировка по
возрастанию.

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

8.3 Функциональное тестирование(2)
Для определения наиболее вероятных наборов данных используют
следующие методы формирования тестовых наборов:
• эквивалентное разбиение;


анализ граничных значений;



анализ причинно-следственных связей;



предположение об ошибке.

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

8.3 Функциональное тестирование(3)
Разработка тестов методом эквивалентного разбиения осуществляется в
два этапа: на первом выделяют классы эквивалентности, а на втором
– формируют тесты.
Выделение
классов
эквивалентности
является
эвристическим
процессом, однако целесообразным считают выделять в отдельные
классы эквивалентности наборы, содержащие допустимые и
недопустимые значения некоторого параметра.
Построение
тестов
заключается
в
использовании
классов
эквивалентности для построения тестов. Этот процесс включает в
себя:
• Назначение каждому классу эквивалентности уникального номера.
• Проектирование новых тестов, каждый из которых покрывает как
можно большее число непокрытых классов эквивалентности, до тех
пор, пока все правильные классы не будут покрыты (только не
общими) тестами.
• Запись тестов, каждый из которых покрывает один и только один из
непокрытых неправильных классов эквивалентности, до тех пор, пока
все неправильные классы не будут покрыты тестами.

8.3 Функциональное тестирование(4)
Недостаток метода эквивалентных разбиения в том, что он не исследует
комбинации входных условий.

Анализ граничных значений.
Граничные условия – это ситуации, возникающие на границах классов
эквивалентности входных значений или около них. Анализ показывает,
что в этих местах резко увеличивается возможность обнаружения
ошибок. Например, если в программе анализа вида треугольника
было записано А + В >=С вместо А + В > С, то это приведет к
ошибочному выводу: линия будет отнесена к одному из видов
треугольника.
Применение метода анализа граничных условий требует определенной
степени творчества и специализации в рассматриваемой проблеме.

8.3 Функциональное тестирование(5)
Существует несколько общих правил для применения этого метода:
• если входное условие описывает область значений, то следует
построить тесты для границ области и тесты с неправильными
входными данными для ситуаций незначительного выхода за границы
области, например, если описана область [1.0, +1.0], то должны быть
сгенерированы тесты: -1.0, +1.0, -1.001 и +1.001;
• если входное условие удовлетворяет дискретному ряду значений, то
следует построить тесты для минимального и максимального значений
и тесты, содержащие значения большие и меньшие этих двух значений,
например, если входной файл может содержать от 1 до 255 записей, то
проверить 0, 1, 255 и 256 записей;
• если существуют ограничения выходных значений, то целесообразно
аналогично тестировать и их: конечно не всегда можно получить
результат вне выходной области, но, тем не менее, стоит рассмотреть
эту возможность;
• если некоторое входное или выходное значение программы является
упорядоченным множеством, например, это последовательный файл,
линейный список или таблица, то следует сосредоточить внимание на
первом и последнем элементах этого множества.

8.3 Функциональное тестирование(6)
Анализ причинно-следственных связей
Анализ причинно-следственных связей, позволяет системно выбирать
высоко результативные тесты. Метод использует алгебру логики и
оперирует понятиями «причина» и «следствие».
Причиной в данном случае называют отдельное входное условие или
класс эквивалентности.
Следствием – выходное условие или преобразование системы.
Идея метода заключается в отнесении всех следствий к причинам, т.е. в
уточнении причинно-следственных связей. Данный метод дает
полезный побочный эффект, позволяя обнаруживать неполноту и
неоднозначность исходных спецификаций.
Построение тестов осуществляют в несколько этапов.
• Сначала спецификация разбивается на «рабочие» участки, стараясь,
по возможности, выделять независимые группы причинноследственных связей в отдельные таблицы.

8.3 Функциональное тестирование(7)



Затем в спецификации определяют множество причин и следствий.
Далее на основе анализа семантического (смыслового) содержания
спецификации строят таблицу истинности, в которой каждой
возможной комбинации причин ставится в соответствие следствие.
При этом целесообразно истину обозначать «1», ложь – «0», а для
обозначения
безразличных
состояний
условий
применять
обозначение «Х», которое предполагает произвольное значение
условия (0 или 1).
• Таблицу снабжают примечаниями, задающими ограничения и
описывающими комбинации причин и/или следствий, которые
являются невозможными из-за синтаксических или внешних
ограничений. При необходимости аналогично строится таблица
истинности для класса эквивалентности.
• Каждую строку таблицы преобразуют в тест. При этом рекомендуется
по возможности следует совмещать тесты из независимых таблиц.
Данный метод позволяет строить высоко результативные тесты ,но его
недостатком является неадекватное исследование граничных
значений.

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

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

Тестирующая
программа s

Тестирующая
программа n

Тестирующая
программа k

Модуль n

Модуль k

а
Тестирование
модулей низшего
уровня

Модуль s

Модуль n

Модуль k

б
Тестирование модуля
следующего уровня

8.4 Тестирование модулей и комплексное
тестирование (2)
Достоинства:
Такой подход обеспечивает полностью автономное тестирование, для
которого просто генерировать тестовые последовательности,
которые передаются в модуль напрямую.
Недостатки:
• при восходящем тестировании, так же как при восходящем
проектировании, серьезные ошибки в спецификациях, алгоритмах и
интерфейсе могут быть обнаружены только на завершающей
стадии работы над проектом;
• для того, чтобы тестировать модули нижних уровней необходимо
разработать специальные тестирующие программы, которые
обеспечивают вызов интересующих нас модулей с необходимыми
параметрами. Причем эти тестирующие программы также могут
содержать ошибки.

8.4 Тестирование модулей и комплексное
тестирование (3)
Нисходящее тестирование
Нисходящее
тестирование
органически
связано
с
нисходящим проектированием и
разработкой:
как
только
проектирование
какого-либо
модуля
заканчивается,
его
кодируют
и
передают
на
тестирование.
В

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

Основной
модуль

Заглушка 1

Заглушка 2

Заглушка 3

а
Основной
модуль

Заглушка 1

Модуль 2

Заглушка 3

Заглушка 21

Заглушка 22

Заглушка 23

б

а) Тестирование
основного модуля

б) Тестирование двух
модулей

8.4 Тестирование модулей и комплексное
тестирование (4)

Достоинства:
ранняя проверка основных решений и качественное многократное
тестирование сопряжения модулей в контексте программного
обеспечения.
При данном подходе имеется возможность согласования с заказчиком
внешнего вида (интерфейса) программного обеспечения.
Недостатки:
отсутствие автономного тестирования модулей.
Поскольку модуль получает данные не непосредственно, а через
вызывающий
модуль,
гораздо
сложнее
обеспечить
его
«достаточное» тестирование.
Комбинированный подход. Чаще всего применяют комбинированный
подход: модули верхних уровней тестируют нисходящим способом,
а модули нижних уровней – восходящим. Этот способ позволяет
начать с тестирования интерфейса и обеспечивает качественное
автономное тестирование модулей низших уровней

8.4 Тестирование модулей и комплексное
тестирование (6)
Комплексное тестирование
Особенностью комплексного тестирования является то, что структурное
тестирование для него практически не применимо. В основном на
данной стадии используют тесты, построенные по методам
эквивалентных классов, граничных условий и предположении об
ошибках.
Критерии завершения отладки.
Все критерии можно разделить на три группы:
• основанные на методологиях проектирования тестов – определенное
количество тестов, полученных по методам анализа причинноследственных связей, анализа граничных значений и предположения
об ошибке, перестают выявлять ошибки;
• основанные на оценке возможного количества ошибок – возможное
количество ошибок оценивают экспертно, или по специальным
методикам , а затем завершают тестирование при нахождении
примерно 93-95% ошибок;
• основанные на исследовании результатов тестирования – строят
график зависимости количества обнаруженных ошибок от времени
тестирования, если он напоминает график, представленный на рис.
9.6, то тестирование можно завершать.

8.5 Оценочное тестирование
Цель тестирование программы на соответствие основным
требованиям.
Оценочное тестирование («тестированием системы в целом»), включает
следующие виды:
• тестирование удобства использования;
• тестирование на предельных объемах;
• тестирование на предельных нагрузках;
• тестирование защиты;
• тестирование удобства эксплуатации;
• тестирование производительности;
• тестирование требований к памяти;
• тестирование конфигурации оборудования;
• тестирование совместимости;
• тестирование удобства установки;
• тестирование надежности;
• тестирование восстановления;
• тестирование удобства обслуживания;
• тестирование документации;
• тестирование процедуры.






Чтобы не видеть здесь видео-рекламу достаточно стать зарегистрированным пользователем.
Чтобы не видеть никакую рекламу на сайте, нужно стать VIP-пользователем.
Это можно сделать совершенно бесплатно. Читайте подробности тут.