ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 20.11.2019
Просмотров: 9471
Скачиваний: 184
Примечание
.
Обычно
на
вопрос
о
цели
тестирования
начинающие
программисты
отвечают
,
что
целью
тестирования
является
«
доказательство
правильности
программы
».
Это
абсолютно
неверное
мнение
.
Г
.
Майерс
[47]
предлагает
очень
удачную
аналогию
для
пояснения
этого
положения
.
Представьте
себе
,
что
вы
пришли
на
прием
к
врачу
и
пожаловались
на
боль
в
боку
.
Врач
выслушал
вас
и
направил
на
обследование
.
Через
некоторое
время
вы
возвращаетесь
к
врачу
с
ворохом
заключений
и
результатов
анализов
,
и
во
всех
этих
бумагах
написано
,
что
все
исследуемые
параметры
у
вас
в
норме
.
Но
бок
то
болит
,
значит
,
что
-
то
не
в
порядке
,
хотя
анализы
этого
и
не
показывают
...
Так
и
сложное
программное
обеспечение
,
безошибочно
работающее
на
всех
тестовых
наборах
,
может
содержать
и
обычно
содержит
некоторое
количество
ошибок
.
Процесс
разработки
программного
обеспечения
,
в
том
виде
,
как
он
определяется
в
современной
модели
жизненного
цикла
программного
обеспечения
,
предполагает
три
стадии
тестирования
:
•
автономное
тестирование
компонентов
программного
обеспечения
;
•
комплексное
тестирование
разрабатываемого
программного
обеспечения
;
•
системное
или
оценочное
тестирование
на
соответствие
основным
критериям
качества
.
Для
повышения
качества
тестирования
рекомендуется
соблюдать
следующие
основные
принципы
:
•
предполагаемые
результаты
должны
быть
известны
до
тестирования
;
•
следует
избегать
тестирования
программы
автором
;
•
необходимо
досконально
изучать
результаты
каждого
теста
;
•
необходимо
проверять
действия
программы
на
неверных
данных
;
•
необходимо
проверять
программу
на
неожиданные
побочные
эффекты
на
неверных
данных
.
Следует
также
иметь
в
виду
,
что
вероятность
наличия
необнаруженных
ошибок
в
части
программы
пропорциональны
количеству
ошибок
уже
найденных
в
этой
части
.
Формирование
тестовых
наборов
.
В
соответствии
с
определением
тестирования
в
начале
данного
параграфа
,
удачным
следует
считать
тест
,
который
обнаруживает
хотя
бы
одну
ошибку
.
С
этой
точки
зрения
хотелось
бы
использовать
такие
наборы
тестов
,
каждый
из
которых
с
максимальной
вероятностью
может
обнаружить
ошибку
.
Формирование
набора
тестов
имеет
большое
значение
,
поскольку
тестирование
является
одним
из
наиболее
трудоемких
этапов
(
от
30
до
60 %
общей
трудоемкости
)
создания
программного
продукта
.
Причем
доля
стоимости
тестирования
в
общей
стоимости
разработки
имеет
тенденцию
возрастать
при
увеличении
сложности
программного
обеспечения
и
повышении
требований
к
их
качеству
.
Существуют
два
принципиально
различных
подхода
к
формированию
тестовых
наборов
:
структурный
и
функциональный
.
Структурный
подход
базируется
на
том
,
что
известка
структура
тестируемого
программного
обеспечения
,
в
том
числе
его
алгоритмы
(«
стеклянный
ящик
»).
В
этом
случае
тесты
строят
так
,
чтобы
проверить
правильность
реализации
заданной
логики
в
коде
программы
.
Функциональный
подход
основывается
на
том
,
что
структура
программного
обеспечения
не
известна
(«
черный
ящик
»).
В
этом
случае
тесты
строят
,
опираясь
на
функциональные
спецификации
.
Этот
подход
называют
также
подходом
,
управляемым
данными
,
так
как
при
его
использовании
тесты
строят
на
базе
различных
способов
декомпозиции
множества
данных
.
Наборы
тестов
,
полученные
в
соответствии
с
методами
этих
подходов
,
обычно
объединяют
,
обеспечивая
всестороннее
тестирование
программного
обеспечения
.
Более
подробное
рассмотрение
перечисленных
вопросов
начнем
с
обсуждения
методов
ручного
контроля
.
9.2.
Ручной
контроль
программного
обеспечения
Ручной
контроль
,
как
указано
выше
,
обычно
используют
на
ранних
этапах
разработки
.
Все
проектные
решения
,
принятые
на
том
или
ином
этапе
,
должны
анализироваться
с
точки
зрения
их
правильности
и
целесообразности
как
можно
раньше
,
пока
их
можно
легко
пересмотреть
.
Поскольку
возможность
практической
проверки
подобных
решений
на
ранних
этапах
разработки
отсутствует
,
большое
значение
имеет
их
обсуждение
,
которое
проводят
в
разных
формах
.
Различают
статический
и
динамический
подходы
к
ручному
контролю
.
При
статическом
подходе
анализируют
структуру
,
управляющие
и
информационные
связи
программы
,
ее
входные
и
выходные
данные
.
При
динамическом
-
выполняют
ручное
тестирование
.,
т
.
е
.
вручную
моделируют
процесс
выполнения
программы
на
заданных
исходных
данных
.
Исходными
данными
для
таких
проверок
являются
:
техническое
задание
,
спецификации
,
структурная
и
функциональная
схемы
программного
продукта
,
схемы
отдельных
компонентов
и
т
.
д
.,
а
для
более
поздних
этапов
-
алгоритмы
и
тексты
программ
,
а
также
тестовые
наборы
.
Доказано
,
что
ручной
контроль
способствует
существенному
увеличению
производительности
и
повышению
надежности
программ
и
с
его
помощью
можно
находить
от
30
до
70 %
ошибок
логического
проектирования
и
кодирования
.
Следовательно
,
один
или
несколько
из
методов
ручного
контроля
обязательно
должны
использоваться
в
каждом
программном
проекте
.
Основными
методами
ручного
контроля
являются
:
•
инспекции
исходного
текста
,
•
сквозные
просмотры
,
•
проверка
за
столом
,
•
оценки
программ
.
Инспекции
исходного
текста
.
Инспекции
исходного
текста
представляют
собой
набор
процедур
и
приемов
обнаружения
ошибок
при
изучении
текста
группой
специалистов
.
В
эту
группу
входят
:
автор
программы
,
проектировщик
,
специалист
по
тестированию
и
координатор
-
компетентный
программист
,
но
не
автор
программы
.
Общая
процедура
инспекции
предполагает
следующие
операции
:
•
участникам
группы
заранее
выдается
листинг
программы
и
спецификация
на
нее
;
•
программист
рассказывает
о
логике
работы
программы
и
отвечает
на
вопросы
инспекторов
;
•
программа
анализируется
по
списку
вопросов
для
выявления
исторически
сложившихся
общих
ошибок
программирования
.
Список
вопросов
для
инспекций
исходного
текста
зависит
,
как
от
используемого
языка
программирования
,
так
и
от
специфики
разрабатываемого
программного
обеспечения
.
В
качестве
примера
ниже
приведен
список
вопросов
,
который
можно
использовать
при
анализе
правильности
программ
,
написанных
на
языке
Pascal.
I.
Контроль
обращений
к
данным
•
Все
ли
переменные
инициализированы
?
•
Не
превышены
ли
максимальные
(
или
реальные
)
размеры
массивов
и
строк
?
•
Не
перепутаны
ли
строки
со
столбцами
при
работе
с
матрицами
?
•
Присутствуют
ли
переменные
со
сходными
именами
?
•
Используются
ли
файлы
?
Если
да
,
то
при
вводе
из
файла
проверяется
ли
завершение
файла
?
•
Соответствуют
ли
типы
записываемых
и
читаемых
значений
?
•
Использованы
ли
нетипизированные
переменные
,
открытые
массивы
,
динамическая
память
?
Если
да
,
то
соответствуют
ли
типы
переменных
при
«
наложении
»
формата
?
Не
выходят
ли
индексы
за
границы
массивов
?
2.
Контроль
вычислений
•
Правильно
ли
записаны
выражения
(
порядок
следования
операторов
)?
•
Корректно
ли
выполнены
вычисления
над
неарифметическими
переменными
?
•
Корректно
ли
выполнены
вычисления
с
переменными
различных
типов
(
в
том
числе
с
использованием
целочисленной
арифметики
)?
•
Возможно
ли
переполнение
разрядной
сетки
или
ситуация
машинного
нуля
?
•
Соответствуют
ли
вычисления
заданным
требованиям
точности
?
•
Присутствуют
ли
сравнения
переменных
различных
типов
?
3.
Контроль
передачи
управления
•
Будут
ли
корректно
завершены
циклы
?
•
Будет
ли
завершена
программа
?
•
Существуют
ли
циклы
,
которые
не
будут
выполняться
из
-
за
нарушения
условия
входа
?
Корректно
ли
продолжатся
вычисления
?
•
Существуют
ли
поисковые
циклы
?
Корректно
ли
отрабатываются
ситуации
«
элемент
найден
»
и
«
элемент
не
найден
»?
4.
Контроль
межмодульных
интерфейсов
•
Соответствуют
ли
списки
параметров
и
аргументов
по
порядку
,
типу
,
единицам
измерения
?
•
Не
изменяет
ли
подпрограмма
аргументов
,
которые
не
должны
изменяться
?
•
Не
происходит
ли
нарушения
области
действия
глобальных
и
локальных
переменных
с
одинаковыми
именами
?
Кроме
непосредственного
обнаружения
ошибок
,
результаты
инспекции
позволяют
программисту
увидеть
другие
сделанные
им
ошибки
,
получить
возможность
оценить
свой
стиль
программирования
,
выбор
алгоритмов
и
методов
тестирования
.
Инспекция
является
способом
раннего
выявления
частей
программы
,
с
большей
вероятностью
содержащих
ошибки
,
что
позволяет
при
тестировании
уделить
внимание
именно
этим
частям
.
Сквозные
просмотры
.
Сквозной
просмотр
,
как
и
инспекция
,
представляет
собой
набор
способов
обнаружения
ошибок
,
осуществляемых
группой
лиц
,
просматривающих
текст
программы
.
Такой
просмотр
имеет
много
общего
с
процессом
инспектирования
,
но
отличается
процедурой
и
методами
обнаружения
ошибок
.
Группа
по
выполнению
сквозного
контроля
состоит
из
трех
-
пяти
человек
:
председатель
или
координатор
,
секретарь
,
фиксирующий
все
ошибки
,
специалист
по
тестированию
,
программист
и
независимый
эксперт
.
Сквозной
просмотр
предполагает
выполнение
следующих
процедур
:
•
участникам
группы
заранее
выдают
листинг
программы
и
спецификацию
на
нее
;
•
участникам
заседания
предлагают
несколько
тестов
;
•
участники
заседания
мысленно
выполняют
каждый
тест
в
соответствии
с
логикой
программы
,
при
этом
состояние
программы
(
значения
переменных
)
отслеживается
на
бумаге
или
доске
;
•
при
необходимости
программисту
задают
вопросы
о
логике
проектирования
и
принятых
допущениях
.
В
большинстве
сквозных
просмотров
при
выполнении
самих
тестов
находят
меньше
ошибок
,
чем
при
опросе
программиста
.
Проверка
за
столом
.
Исторически
данный
метод
ручного
тестирования
появился
первым
,
так
как
он
не
требует
наличия
группы
специалистов
.
Это
-
проверка
исходного
текста
или
сквозные
просмотры
,
выполняемые
одним
человеком
,
который
читает
текст
программы
,
проверяет
его
на
наличие
возможных
ошибок
по
специальному
списку
часто
встречающихся
ошибок
и
«
пропускает
»
через
программу
тестовые
данные
.
Исходя
из
принципов
тестирования
,
проверку
за
столом
должен
проводить
человек
,
не
являющийся
автором
программы
.
Метод
наименее
результативен
,
так
как
проверка
представляет
собой
полностью
неупорядоченный
процесс
,
при
ней
отсутствует
обмен
мнениями
и
здоровая
конкуренция
.
Оценка
программ
.
Этот
метод
непосредственно
не
связан
с
тестированием
,
но
его
использование
также
улучшает
качество
программирования
.
Его
используют
для
анонимной
оценки
программы
в
терминах
ее
общего
качества
,
простоты
эксплуатации
и
ясности
.
Цель
метода
-
обеспечить
сравнительно
объективную
оценку
и
самооценку
программистов
.
Такая
оценка
выполняется
следующим
образом
.
Выбирается
программист
,
который
должен
выполнять
обязанности
администратора
процесса
.
Администратор
набирает
группу
от
шести
до
20-
ти
участников
,
которые
должны
заниматься
разработкой
сходных
программ
.
Каждому
участнику
предлагается
представить
для
рассмотрения
две
программы
,
с
его
точки
зрения
-
наилучшую
и
наихудшую
.
Отобранные
программы
случайным
образом
распределяются
между
участниками
.
Им
дают
по
четыре
программы
-
две
наилучшие
и
две
наихудшие
,
но
не
говорят
,
какие
программы
плохие
,
а
какие
-
хорошие
.
Программист
просматривает
эти
программы
и
заполняет
анкету
,
в
которой
оценивает
качество
программ
по
семибалльной
шкале
.
После
этого
результаты
оценки
сверяют
,
а
проверяющий
дает
общий
комментарий
и
рекомендации
по
улучшению
программ
.
9.3.
Структурное
тестирование
Структурное
тестирование
называют
также
тестированием
по
«
маршрутам
»,
так
как
в
этом
случае
тестовые
наборы
формируют
путем
анализа
маршрутов
,
предусмотренных
алгоритмом
.
Под
маршрутами
при
этом
понимают
последовательности
операторов
программы
,
которые
выполняются
при
конкретном
варианте
исходных
данных
.
В
основе
структурного
тестирования
лежит
концепция
максимально
полного
тестирования
всех
маршрутов
программы
.
Так
,
если
алгоритм
программы
включает
ветвление
,
то
при
одном
наборе
исходных
данных
может
быть
выполнена
последовательность
операторов
,
реализующая
действия
,
которые
предусматривает
одна
ветвь
,
а
при
втором
-
другая
.
Соответственно
,
для
программы
будут
существовать
маршруты
,
различающиеся
выбранным
при
ветвлении
вариантом
.
Считают
,
что
программа
проверена
полностью
,
если
с
помощью
тестов
удается
осуществить
выполнение
программы
по
всем
возможным
маршрутам
передач
управления
.
Однако
нетрудно
видеть
,
что
даже
в
программе
среднего
уровня
сложности
число
неповторяющихся
маршрутов
может
быть
очень
велико
,
и
,
следовательно
,
полное
или
исчерпывающее
тестирование
маршрутов
,
как
правило
,
невозможно
.
Структурный
подход
к
тестированию
имеет
ряд
недостатков
.
Так
тестовые
наборы
,
построенные
по
данной
стратегии
:
•
не
обнаруживают
пропущенных
маршрутов
;
•
не
обнаруживают
ошибок
,
зависящих
от
обрабатываемых
данных
,
например
,
в
операторе
if
(a - b) < eps -
пропуск
функции
абсолютного
значения
abs
проявится
только
,
если
а
<
Ь
;
•
не
дают
гарантии
,
что
программа
правильна
,
например
,
если
вместо
сортировки
по
убыванию
реализована
сортировка
по
возрастанию
.
Для
формирования
тестов
программу
представляют
в
виде
графа
,
вершины
которого
соответствуют
операторам
программы
,
а
дуги
представляют
возможные
варианты
передачи
управления
.
Ниже
приведен
текст
программы
,
которая
определяет
значение
х
в
зависимости
от
значений
параметров
процедуры
.
Алгоритм
этой
программы
представлен
на
рис
. 9.2,
а
,
а
соответствующий
граф
передач
управления
-
на
рис
. 9.2,
6.
Procedure
т
(
а
, b: r
еа
1; var x: real);
begin
if (a1) and (b=0) then x: =x/a;
if (a=2) or (x>1) then x: =x+1;
end;
Формирование
тестовых
наборов
для
тестирования
маршрутов
может
осуществляться
по
нескольким
критериям
:
•
покрытие
операторов
;
•
покрытие
решений
(
переходов
);
•
покрытие
условий
;
•
покрытие
решений
/
условий
;
•
комбинаторное
покрытие
условий
.
Покрытие
операторов
.
Критерий
покрытия
операторов
подразумевает
такой
подбор
тестов
,
чтобы
каждый
оператор
программы
выполнялся
,
по
крайней
мере
,
один
раз
.
Это
необходимое
,
но
недостаточное
условие
для
приемлемого
тестирования
.
Поясним
сказанное
примером
.
Для
фрагмента
,
алгоритм
и
граф
которого
представлены
на
рис
. 9.2,
можно
было
бы
выполнить
каждый
оператор
один
раз
,
задав
в
качестве
входных
данных
а
= 2, b =
О
,
х
= 3.
Но
при
этом
из
второго
условия
следует
,
что
переменная
х
может
принимать
любое
значение
,
и
в
некоторых
версиях
языка
Pascal
это
значение
проверяться
не
будет
(!).
Кроме
того
:
•
если
при
написании
программы
в
первом
условии
указано
: (
а
> 1) or (b = 0),
то
ошибка
обнаружена
не
будет
;
•
если
во
втором
условии
вместо
х
> 1
записано
х
> 0,
то
эта
ошибка
тоже
не
будет
обнаружена
;
•
существует
путь
1-2-4-6 (
см
.
рис
. 9.2,
б
),
в
котором
х
вообще
не
меняется
и
,
если
здесь
есть
ошибка
,
она
не
будет
обнаружена
.
Таким
образом
,
хотя
при
тестировании
действительно
необходимо
задавать
исходные
данные
так
,
чтобы
все
операторы
программы
были
выполнены
хотя
бы
один
раз
,
для
проверки
программы
этого
явно
недостаточно
.