Обратная связь
|
Технические требования к тестированию. ТЕСТИРОВАНИЕ
Общие понятия тестирования программ
Тестирование – это процесс исполнения программы с целью обнаружения ошибок.
Программа тестируется не для того, чтобы показать, что она работает, а скорее наоборот – тестирование начинается с предположения, что в ней есть ошибки (это предположение справедливо практически для любой программы), а затем уже обнаруживается их максимально возможное число.
Следствия:
- Тестирование – процесс деструктивный (т. е. обратный созидательному, конструктивному).
- Тестовый прогон удачный, если в процессе его выполнения обнаружена ошибка, и неудачный, если получен корректный результат.
Целью тестирования является получение результатов по конкретным данным, а также контроль качества программы.
Тестирование должно включать проверку всех ветвей программы и должно включать минимальный набор примеров. При тестировании нельзя предусмотреть такие всевозможные ситуации, но надо добиваться определенных результатов.
Существует две стратегии тестирования:
- как черного ящика- когда реализация системы недоступна тестеровщикам, а тестируется только ее интерфейс.
- как белого ящика- когда код программ доступен тестеровщикам и используется в качестве источника информации о системе.
Стратегия черного ящика
При использовании этой стратегии программа рассматривается как черный ящик. Иными словами, такое тестирование имеет целью выяснение обстоятельств, в которых поведение программы не соответствует ее спецификации. Тестовые же данные используются только в соответствии со спецификацией программы (т. е. без учета знаний о ее внутренней структуре).
При таком подходе обнаружение всех ошибок в программе является критерием исчерпывающего входного тестирования. Последнее может быть достигнуто, если в качестве тестовых наборов использовать все возможные наборы входных данных.
Но построение исчерпывающего входного теста невозможно. Это подтверждается двумя аргументами:
во-первых,нельзя создать тест, гарантирующий отсутствие ошибок;
во-вторых, разработка таких тестов противоречит экономическим требованиям.Поскольку исчерпывающее тестирование исключается, нашей целью должна стать максимизация результативности капиталовложений в тестирование (иными словами, максимизация числа ошибок, обнаруживаемых одним тестом).
Стратегия белого ящика
Стратегия белого ящика, или стратегия тестирования, управляемого логикой программы, позволяет исследовать внутреннюю структуру программы. В этом случае тестирующий получает тестовые данные путем анализа логики программы.
Рис. 7.1. Метод белого ящика.
На рисунке видно, что на основе требований к системе создается реализация и тестовая модель системы. Тестирование есть сопоставление двух этих представлений с целью выявить их несоответствия. Чем независимее друг от друга будут эти представления, тем больше прока от их сопоставления. Иначе, если тестеровщики существенно используют информацию о реализации системы при составлении тестов, то они могут невольно внести в тесты ошибки реализации. Найденное при тестировании несоответствие – это еще не ошибка, поскольку сами тестеровщики могли неправильно понять требования, в тестах и средствах тестирования могли быть ошибки.
Подразумевается, что программа проверена полностью, если с помощью тестов удается осуществить выполнение этой программы по всем возможным маршрутам ее потока (графа) передач управления.
Но число не повторяющих друг друга маршрутов в программе – астрономическое. Следовательно, исчерпывающее тестирование маршрутов невозможно.
Вывод: хотя исчерпывающее входное тестирование предпочтительнее исчерпывающего тестирования маршрутов, ни то, ни другое не могут стать полезными стратегиями, потому что оба они нереализуемы. Возможно, поэтому реальным путем, который позволит создать хорошую, но, конечно, не абсолютную стратегию, является сочетание тестирования программы как черного и так и белого ящиков.
У Г. Майерса сформулированы основные принципы организации тестирования:
- Описание предполагаемых значений выходных данных или результатов должно быть необходимой частью тестового набора.
- Следует избегать тестирования программы ее автором.
- Программирующая организация не должна сама тестировать разработанные ею программы.
- Необходимо досконально изучать результаты применения каждого теста.
- Тесты для неправильных и непредусмотренных входных данных следует разрабатывать так же тщательно, как для правильных предусмотренных.
- Необходимо проверять не только, делает ли программа то, для чего она предназначена, но и не делает ли она то, что не должна делать.
- Не следует выбрасывать тесты, даже если программа уже ненужна.
- Нельзя планировать тестирование в предположении, что ошибки не будут обнаружены.
- Вероятность наличия необнаруженных ошибок в части программы пропорциональна числу ошибок, уже обнаруженных в этой части.
- Тестирование — процесс творческий.
Ошибка
Задача любого тестировщика заключается в нахождении наибольшего количества ошибок, поэтому он должен хорошо знать наиболее часто допускаемые ошибки и уметь находить их за минимально короткий период времени. Остальные ошибки, которые не являются типовыми, обнаруживаются только тщательно созданными наборами тестов. Однако, из этого не следует, что для типовых ошибок не нужно составлять тесты.
Для классификации ошибок определим термин «ошибка».
Ошибка – это расхождение между вычисленным, наблюдаемым и истинным, заданным или теоретически правильным значением.
|
Классификация ошибок
По времени появления ошибки можно разделить на три вида:
·структурные ошибки набора;
·ошибки компиляции;
·ошибки периода выполнения.
Структурные ошибки возникают непосредственно при наборе программы или при ее компиляции, если среда не разделяет первые два типа ошибок.
К данному типу ошибок относятся такие как: несоответствие числа открывающих скобок числу закрывающих, отсутствие парного оператора, неправильное употребление синтаксических знаков и т. п.
Ошибки компиляции возникают из-за ошибок в тексте кода. Они включают ошибки в синтаксисе, неверное использование конструкций языка, использование несуществующих объектов или свойств, методов у объектов.
Ошибки периода выполнения возникают, когда программа выполняется и компилятор (или операционная система, виртуальная машина) обнаруживает, что оператор делает попытку выполнить недопустимое или невозможное действие. Например, деление на ноль.
В теоретической информатике программные ошибки классифицируют по степени нарушения логики на:
·синтаксические;
·семантические;
·прагматические.
Синтаксические ошибки заключаются в нарушении правописания или пунктуации в записи выражений, операторов и т. п., т. е. в нарушении грамматических правил языка. В качестве примеров синтаксических ошибок можно назвать:
· пропуск необходимого знака пунктуации;
· несогласованность скобок;
· пропуск нужных скобок;
· неверное написание зарезервированных слов;
· отсутствие описания массива.
Все ошибки данного типа обнаруживаются компилятором.
Семантические ошибки заключаются в нарушении порядка операторов, параметров функций и употреблении выражений. Семантические ошибки также обнаруживаются компилятором.
Прагматические ошибки (или логические) заключаются в неправильной логике алгоритма, нарушении смысла вычислений и т. п. Они являются самыми сложными и крайне трудно обнаруживаются. Компилятор может выявить только следствие прагматической ошибки.
На этапе тестирования ищутся прагматические ошибки периода выполнения, так как остальные выявляются в процессе программирования. Их можно классифицировать следующим образом:
Ошибка адресации – ошибка, состоящая в неправильной адресации данных (например, выход за пределы участка памяти).
Ошибка ввода-вывода – ошибка, возникающая в процессе обмена данными между устройствами памяти, внешними устройствами.
Ошибка вычисления – ошибка, возникающая при выполнении арифметических операций (например, разнотипные данные, деление на нуль и др.).
Ошибка интерфейса – программная ошибка, вызванная несовпадением характеристик фактических и формальных параметров (как правило, семантическая ошибка периода компиляции, но может быть и логической ошибкой периода выполнения).
Ошибка обращения к данным – ошибка, возникающая при обращении программы к данным (например, выход индекса за пределы массива, не инициализированные значения переменных и др.).
Ошибка описания данных – ошибка, допущенная в ходе описания данных.
Технические требования к тестированию.
Тест - набор данных, с помощью которого производится тестирование, он включает подмножество допустимых входов в программу.
В технической диагностике тест - это последовательность наборов сигналов (исходных данных), которые подаются на вход изделия, и соответствующие им наборы эталонных правильных сигналов (результирующих данных), которые должны быть получены на выходе. Для каждого тестового набора указываются координаты (точки) ввода исходных данных и координаты (точки) контроля результатов. Кроме того, при тестировании необходимо задавать допуски на отклонение результирующих данных от эталонных, в пределах которых следует, что полученные результаты соответствуют эталонным. Степень отклонения получаемых результатов от эталонов используется для оценки качества изделий и соответствия их техническим требованиям.
В ряде случаев процесс исполнения программ и получаемые результаты зависят от непредсказуемого изменения входных и промежуточных данных, а также от реального времени. Вследствие этого невозможно создать единственный универсальный метод тестирования и приходится применять ряд значительно различающихся категорий тестов. Каждая категория тестов отличается целевыми задачами, проверяемыми компонентами программы и методами оценки результатов. Только совместное и систематическое применение различных тестов тестирования позволяет достичь высокого качества функционирования программ.
Ручной тест – это последовательность действий тестеровщика, которую он (или разработчик) может воспроизвести и ошибка произойдет. Как правило, в средствах контроля ошибками такие последовательности действий содержатся в описании ошибки.
Автоматический тест – это некоторая программа, которая воздействует на систему и проверяет то или иное ее свойство. Автоматический тест, по сравнению с "ручным", можно легко воспроизводить без участия человека. Можно создавать наборы тестов и прогонять их часто, например, в режиме регрессионного тестирования. Кроме того, автоматические тесты можно генерировать по более высокоуровневым спецификациям.
Таким образом, преимущества автоматических тестов перед "ручными" очевидны.
Виды тестирования. Не претендуя на полноту, выделим следующие виды тестирования.
- Модульное тестирование - тестируется отдельный модуль, в отрыве от остальной системы. Самый распространенный случай применения – тестирования модуля самим разработчиком, проверка того, что отдельные модули, классы, методы делают действительно то, что от них ожидается. Различные среды разработки широко поддерживают средства модульного тестирования – например, популярная свободно распространяемая библиотека для Visual Studio NUnit, JUnit для Java и т.д. Созданные разработчиком модульные тесты часто включаются в пакет регрессионных тестов и таким образом, могут запускаться многократно.
- Интеграционное тестирование – две и более компонент тестируются на совместимость. Это очень важный вид тестирования, поскольку разные компоненты могут создаваться разными людьми, в разное время, на разных технологиях. Этот вид тестирования, безусловно, должен применяться самими программистами, чтобы, как минимум, удостовериться, что все живет вместе в первом приближении. Далее тонкости интеграции могут исследовать тестеровщики. Необходимо отметить, что такого рода ошибки – "ошибки на стыках" - непросто обнаруживать и устранять. Во время разработки все компоненты все вместе не готовы, интеграция откладывается, а в конце обнаруживаются трудные ошибки (в том смысле, что их устранение требует существенной работы). Здесь выходом является ранняя интеграция системы и в дальнейшем использование практики постоянной интеграции.
- Системное тестирование – это тестирование всей системы в целом, как правило, через ее пользовательский интерфейс. При этом тестеровщики, менеджеры и разработчики акцентируются на том, как ПО выглядит и работает в целом, удобно ли оно, удовлетворяет ли она ожиданиям заказчика. При этом могут открываться различные дефекты, такие как неудобство в использовании тех или иных функций, забытые или "скудно" понятые требования.
— альфа-тестирование — имитация реальной работы с системой штатными разработчиками либо реальная работа с системой потенциальными пользователями/заказчиком на стороне разработчика. Часто альфа-тестирование применяется для законченного продукта в качестве внутреннего приемочного тестирования. Иногда альфа-тестирование выполняется под отладчиком или с использованием окружения, которое помогает быстро выявлять найденные ошибки. Обнаруженные ошибки могут быть переданы тестировщикам для дополнительного исследования в окружении, подобном тому, в котором будет использоваться ПО;
— бета-тестирование — в некоторых случаях выполняется распространение версии с ограничениями (по функциональности или времени работы) для некоторой группы лиц с тем, чтобы убедиться, что продукт содержит достаточно мало ошибок. Иногда бета-тестирование выполняется для того, чтобы получить обратную связь о продукте от его будущих пользователей.
- Регрессионное тестирование – тестирование системы в процессе ее разработки и сопровождение на регресс. То есть проверяется, что изменения системы не ухудшили уже существующей функциональности. Для этого создаются пакеты регрессионных тестов, которые запускаются с определенной периодичностью – например, в пакетном режиме, связанные с процедурой постоянной интеграции.
- Проверка в нормальных условиях.Данная проверка производится на основе данных, которые характерны для реальных условий функционирования программы.
Результат такого теста — показ правильных результатов для характерных совокупностей данных.
- Нагрузочное тестирование – тестирование системы на корректную работу с большими объемами данных. Например, проверка баз данных на корректную обработку большого (предельного) объема записей, исследование поведение серверного ПО при большом количестве клиентских соединений, эксперименты с предельным трафиком для сетевых и телекоммуникационных систем, одновременное открытие большого числа файлов, проектов и т.д.
- Стрессовое тестирование – тестирование системы на устойчивость к непредвиденным ситуациям. Этот вид тестирования нужен далеко не для каждой системы, так как подразумевает высокую планку качества.
Для данной проверки значения данных подбирают так, чтобы они лежали за пределами допустимой области изменения. Данные должны содержать пробелы, цифры и буквы в разной последовательности и сочетании.
- Приемочное тестирование – тестирование, выполняемое при приемке системы заказчиков. Более того, различные стандарты часто включают в себя наборы приемочных тестов. Например, существует большой пакет тестов, поддерживаемых компанией Sun Microsystems, которые обязательны для прогона для всех новых реализаций Java-машины. Считается, что только после того, как все эти тесты успешно проходят, новая реализация вправе называться Java.
Ручные методы тестирования:
- Инспекции исходного текста
- Сквозной просмотр
- Проверка за столом
Инспекции исходного текста представляют собой набор процедур и приемов обнаружения ошибок при изучении (чтении) текста группой специалистов.
Инспектирующая группа включает обычно четыре человека, один из которых выполняет функции председателя.
Инспекционное заседание разбивается на две части:
- Программиста просят рассказать о логике работы программы. Во время беседы возникают вопросы, преследующие цель обнаружения ошибки.
- Программа анализируется по списку вопросов для выявления исторически сложившихся общих ошибок программирования.
По окончании заседания программисту передается список найденных ошибок.
Сквозной просмотр, представляет собой набор процедур и способов обнаружения ошибок, осуществляемых группой лиц, просматривающих текст программы. Такой просмотр имеет много общего с процессом инспектирования, но их процедуры несколько отличаются и, кроме того, здесь используются другие методы обнаружения ошибок.
Подобно инспекции, сквозной просмотр проводится как непрерывное заседание, продолжающееся один или два часа. Группа по выполнению сквозного просмотра состоит из 3–5 человек. Участникам заранее, за несколько дней до заседания, раздаются материалы, позволяющие им ознакомиться с программой. Лицо, назначенное тестирующим, предлагает собравшимся небольшое число написанных на бумаге тестов, представляющих собой наборы входных данных (и ожидаемых выходных данных) для программы или модуля. Во время заседания каждый тест мысленно выполняется. Это означает, что тестовые данные подвергаются обработке в соответствии с логикой программы. По окончании заседания программисту передается список найденных ошибок.
Проверка за столом может рассматриваться как проверка исходного текста или сквозные просмотры, осуществляемые одним человеком, который читает текст программы, проверяет его по списку ошибок и (или) пропускает через программу тестовые данные. Большей частью проверка за столом является относительно непродуктивной.
Все методологии тестирования можно разделить на следующие:
стратегии черного ящика:
− эквивалентное разбиение;
− анализ граничных значений;
− применение функциональных диаграмм;
− предположение об ошибке;
стратегии белого ящика:
− покрытие операторов;
− покрытие решений;
− покрытие условий;
− покрытие решений/условий.
При проектировании эффективного теста программы рекомендуется использовать если не все эти методы, то, по крайней мере, большинство из них, так как каждый метод имеет определенные достоинства и недостатки
Cтратегии белого ящика.
Покрытие операторов: критерием покрытия являетсявыполнение каждого оператора программы, по крайней мере, один раз.Выполнение каждого оператора, по крайней мере, один раз есть необходимое, но недостаточное условие для приемлемого тестирования по принципу белого ящика
Более сильный критерий покрытия логики программы (и метод тестирования) известен какпокрытие решений, илипокрытие переходов. Каждое направление перехода должно быть реализовано по крайней мере один раз. (Покрытие решений требует, чтобы каждое решение имело результатом значения истина и ложь и при этом каждый оператор выполнялся бы, по крайней мере, один раз. Альтернативный и более легкий способ выражения этого требования состоит в том, чтобы каждое решение имело результатом значения истина и ложь и что каждой точке входа (включая каждуюcase-единицу) должно быть передано управление при вызове программы, по крайней мере, один раз.)
Лучшим критерием (и методом) по сравнению с предыдущим являетсяпокрытие условий. В этом случае записывают число тестов, достаточное для того, чтобывсе возможные результаты каждого условия в решении выполнялись, по крайней мере, один раз.
Методпокрытие решений/условий требует такого достаточного набора тестов, чтобывсе возможные результаты каждого условия в решении, все результаты каждого решения выполнялись, по крайней мере, один раз и каждой точке входа передавалось управление, по крайней мере, один раз.
Недостатком критерия покрытия решений/условий является невозможность его применения для выполнения всех результатов всех условий
Cтратегии черного ящика.
Эквивалентное разбиение
- каждый тест должен включать столько различных входных условий, сколько это возможно, с тем, чтобы минимизировать общее число необходимых тестов.
- необходимо пытаться разбить входную область программы на конечное число классов эквивалентности так, чтобы можно было предположить (конечно, не абсолютно уверенно), что каждый тест, являющийся представителем некоторого класса, эквивалентен любому другому тесту этого класса.
Иными словами, если один тест класса эквивалентности обнаруживает ошибку, то следует ожидать, что и все другие тесты этого класса эквивалентности будут обнаруживать ту же самую ошибку. Наоборот, если тест не обнаруживает ошибки, то следует ожидать, что ни один тест этого класса эквивалентности не будет обнаруживать ошибки.
Метод эквивалентного разбиения значительно лучше случайного подбора тестов, но имеет свои недостатки. Основной из них - пропуск определенных типов высокоэффективных тестов (т.е. тестов, характеризующихся большой вероятностью обнаружения ошибок).
Анализ граничных значений.
Граничные условия – это ситуации, возникающие непосредственно на границе, выше или ниже границ входных и выходных классов эквивалентности. Анализ граничных значений отличается от эквивалентного разбиения в двух отношениях:
- Выбор любого элемента в классе эквивалентности в качестве представительного при анализе граничных значений осуществляется таким образом, чтобы проверить тестом каждую границу этого класса.
- При разработке тестов рассматривают не только входные условия (пространство входов), но и пространство результатов (т. е. выходные классы эквивалентности).
Общие правила метода «анализ граничных условий»:
- Построить тесты для границ области и тесты с неправильными входными данными для ситуаций незначительного выхода за границы области, если входное условие описывает область значений.
- Построить тесты для минимального и максимального значений условий и тесты, большие и меньшие этих значений, если входное условие удовлетворяет дискретному ряду значений.
- Использовать первое правило для каждого выходного условия.
- Использовать второе правило для каждого выходного условия.
- Если вход или выход программы есть упорядоченное множество (например, последовательный файл, линейный список, таблица), то сосредоточить внимание на первом и последнем элементах этого множества.
- Попробовать свои силы в поиске других граничных условий.
Анализ граничных условий - один из наиболее полезных методов проектирования тестов. Но он часто оказывается неэффективным из-за того, что граничные условия иногда едва уловимы, а их выявление весьма трудно.
Применение функциональных диаграмм
Функциональная диаграмма представляет собой формальный язык, на который транслируется спецификация, написанная на естественном языке.
Построение тестов этим методом осуществляется в несколько этапов:
- Спецификация разбивается на «рабочие» участки.
- В спецификации определяются причины и следствия.
- Анализируется семантическое содержание спецификации, которая преобразуется в булевский граф, связывающий причины и следствия. Это и есть функциональная диаграмма.
- Диаграмма снабжается примечаниями (комментариями), задающими ограничения и описывающими комбинации причин и (или) следствий, которые являются невозможными из-за синтаксических или внешних ограничений.
- Путем методического прослеживания состояний условий диаграммы она преобразуется в таблицу решений с ограниченными входами. Каждый столбец таблицы решений соответствует тесту.
- Столбцы таблицы решений преобразуются в тесты.
Базовые символы для записи функциональных диаграмм
Предположение об ошибке
Основная идея этого метода заключается в том, чтобы перечислить в некотором списке возможные ошибки или ситуации, в которых они могут появиться, а затем на основе этого списка написать тесты.
Стратегия
Методологии проектирования тестов могут быть объединены в общую стратегию:
1. Если спецификация содержит комбинации входных условий, то начать рекомендуется с применения метода функциональных диаграмм. Однако, данный метод достаточно трудоемок.
2. В любом случае необходимо использовать анализ граничных значений. Этот метод включает анализ граничных значений входных и выходных переменных. Анализ граничных значений дает набор дополнительных тестовых условий, но, как замечено в разделе, посвященном функциональным диаграммам, многие из них (если не все) могут быть включены в тесты метода функциональных диаграмм.
3. Определить правильные и неправильные классы эквивалентности для входных и выходных данных и дополнить, если это необходимо, тесты, построенные на предыдущих шагах.
4. Для получения дополнительных тестов рекомендуется использовать метод предположения об ошибке.
5. Проверить логику программы на полученном наборе тестов. Для этого нужно воспользоваться критерием покрытия решений, покрытия условий, покрытия решений/условий либо комбинаторного покрытия условий (последний критерий является более полным).
|
|