Файл: Отладка и тестирование программ: основные подходы и ограничения (Метод черного ящика).pdf
Добавлен: 31.03.2023
Просмотров: 457
Скачиваний: 1
СОДЕРЖАНИЕ
Основные принципы отладки и тестирования
Современное состояние технологии отладки программного обеспечения
Цели и задачи тестирования программного обеспечения
Современное состояние технологии тестирования программного обеспечения
Стратегии тестирования программного обеспечения
Наблюдаемость и управляемость логики программного обеспечения
Проблема абстрактной диагностики в терминах наблюдаемости и управляемости программного обеспечения
Как правило, перед кодированием программы анализ конструкции и проверка кода выполняются в рамках статического тестирования [13.]. Как только код написан, могут применяться различные другие методы статического анализа, основанные на исходном коде [14.]. Различные виды и этапы тестирования, предназначенные для разных уровней интеграции и различных режимов сбоев программного обеспечения, обсуждаются в большом количестве литературы [15., 16., 17.]. Например, тестирование, проводимое на более поздних этапах (например, тесты внешних функций, системные тесты и т. д.) – это тестирование «черного ящика», основанное на внешних спецификациях, и, следовательно, не подразумевающее понимания реализаций детального кода. Как правило, системное тестирование направлено на ключевые аспекты продукта, такие как восстановление, безопасность, производительность, конфигурация оборудования, программного обеспечения и т. д. Тестирование в процессе производства и внедрения обычно включает определенный уровень критериев приемлемости для клиента. Многие компании-разработчики разрабатывают предварительные бета-программы для своих клиентов.
Тестирование программного обеспечения имеет следующий жизненный цикл:
- Анализ потребностей: необходимо выполнить этап анализа потребностей жизненного цикла тестирования программного обеспечения;
- Анализ проекта: на этом этапе специалисты по тестированию и дизайна определяют, какая часть проекта и какие параметры должны использоваться при тестировании;
- Дизайн тестирования: на этом этапе стратегия тестирования становится понятной;
- Запуск тестирования: запуск тестирования – любые ошибки будут сообщены разработчику;
- Отчет об испытаниях: после завершения испытаний последние результаты публикуются в форме отчета, который определяет, является ли программное обеспечение пригодным для использования или нет.
Современное состояние технологии тестирования программного обеспечения
Критика Дейкстры [18.], «Тестирование программ может использоваться для выявления наличия ошибок, но не для выявления их отсутствия», хорошо известна. С его точки зрения, любой объем тестирования представляет собой лишь небольшую выборку из всех возможных вычислений и поэтому никогда не является достаточным для обеспечения ожидаемого поведения программы при всех возможных условиях. Он утверждал, что «степень, в которой может быть установлена корректность программы, является не просто функцией внешних спецификаций и поведения программы, а критически зависит от ее внутренней структуры». Однако тестирование стало предпочтительным процессом удовлетворения потребностей программного обеспечения. Это связано, прежде всего, с тем, что никакой другой подход, основанный на более формальных методах, не приблизился бы к обеспечению масштабируемости и удовлетворению интуитивных потребностей «разработчика» в программировании. Гамлет [19.] связал хорошее тестирование с измерением надежности тестируемого программного обеспечения в некотором статистическом смысле. Отсутствие или наличие сбоев, выявленных самим тестированием, не измеряет надежность программного обеспечения, если только не существует какого-либо способа количественно оценить свойства тестирования, чтобы убедиться, что адекватные параметры тестирования, включая тестируемость целевого программного обеспечения, были охвачены. Методы планирования тестирования, основанные на разделении функциональности, данных, рабочих профилей конечного пользователя [20.] и т.д. очень полезны и популярны в исследованиях тестирования и среди специалистов-практиков. Многие из современных технологий в тестировании основаны на этих идеях.
Как обсуждалось ранее, тестирование – это, по сути, выборка пространства выполнения программы. Следовательно, возникает естественный вопрос: когда мы должны прекратить тестирование? Учитывая то, что мы не можем реально показать, что в программе больше нет ошибок, мы можем использовать только эвристические аргументы, основанные на завершенности и изощренности усилий по тестированию, и тенденциях в результате обнаружения дефектов для того, чтобы доказать вероятность более низкого риска оставшихся дефектов. Примерами метрик, используемых в процессе тестирования [21.], которые нацелены на обнаружение дефектов и размер кода, являются: размер продукта и выпуска с течением времени, частота обнаружения дефектов с течением времени, отставание по дефектам с течением времени и так далее. Некоторые практические метрики, которые характеризуют процесс тестирования – прогресс тестирования во времени (запланированный, предпринятый, фактический), процент выполненных тестовых случаев и т.д. В некоторых организациях использование метрик покрытия тестов (например, охват кода) используется для описания завершенности тестирования. Использование методологии Ортогональной классификации дефектов [22.] позволяет дать более семантическую характеристику как природы обнаруженных дефектов, так и завершенности процесса тестирования.
Анализ исходного кода для выявления потенциальных дефектов является хорошо развитой отраслью разработки программного обеспечения [24.]. Типичный метод работы состоит в том, чтобы сделать целевой код доступным для инструмента анализа кода. Затем инструмент будет искать некий класс проблем и помечать их как потенциальных кандидатов для изучения и исправления. В анализе исходного кода есть явные преимущества: это можно сделать до того, как появится исполняемая версия программы. Определенный класс ошибок, например, утечки памяти, легче выявить при анализе, чем при тестировании. Неисправность легче локализовать, так как симптомы имеют тенденцию быть причиной. Типичный анализ выполняется с использованием компилятора или анализатора, привязанного к языку программы, который создает представление, такое как граф вызовов, граф управления или граф потока данных программы. Многие коммерческие и исследовательские инструменты доступны в этой области.
Любые действия с тестированием состоят из четырех основных частей: разработка тестового набора, создание тестового набора, выполнение тестового набора и отладка [28.]. Из-за большого объема необходимого тестирования большинство организаций переходят от тестирования в преимущественно ручном режиме к автоматизированному тестированию. Из-за сложности рассматриваемых вопросов наиболее легко поддающимся автоматизации является выполнение тестов. Это предполагает, что контрольные примеры уже определены и записаны вручную (или получены с помощью инструмента) и могут быть выполнены в автоматизированной среде выполнения тестов с точки зрения планирования, регистрации результатов (успех или неудача), захвата деталей отказавшей среды окружения, и так далее. Для тестирования, которое требует явного использования графических пользовательских интерфейсов, автоматизация выполнения тестовых примеров уже привела к значительному увеличению производительности в отрасли. Существует целый ряд коммерческих и исследовательских инструментов тестирования.
Автоматизация проектирования тестовых наборов (и, следовательно, создание тестовых наборов) – является еще одной областью для изучения [25.]. Чтобы автоматизировать разработку функциональных тестовых примеров, необходимо иметь формальное описание спецификаций поведения программного обеспечения, в результате чего получается модель поведения ПО. Как обсуждалось ранее, это формальное описание не охватывается типичными коммерческими организациями. В то время как использование технологии конечных автоматов [26.] начинает завоевывать популярность в сообществе валидации моделей, ее использование в более широком сообществе тестирования промышленного программного обеспечения в лучшем случае ограничено. Растущее принятие UML (Unified Modeling Language, рус. «унифицированный язык моделирования») разработчиками в качестве языка проектирования может предоставить возможность для получения более формального описания спецификаций программного обеспечения. Тем не менее, в UML все еще не хватает конструкций, чтобы быть эффективным языком для получения реалистичных спецификаций тестовых примеров [27.].
Для программного обеспечения, которое прошло через много версий, одним из острых вопросов была проверка спецификаций предыдущих релизов по сравнению с текущим [29.]. Обычно это делается посредством выполнения «регрессионных» тестовых случаев (которые использовались для проверки предыдущих релизов) по сравнению с текущим релизом. В большинстве реальных сред автоматическое отслеживание не установлено среди тестовых случаев (то есть никто не знает, почему тестовый пример был добавлен или он все еще действителен). Кроме того, связь между требованиями к коду и финальной реализацией не отслеживается между версиями. Следовательно, регрессионное тестирование не только проверяет, что более ранние спецификации все еще действительны, но также выявляет проблемы обратной совместимости. Хотя существует очевидная необходимость продолжать добавлять набор регрессионных тестов, исходя из опасений относительно совокупных спецификаций для текущей версии программы, собранная неадекватная информация делает невозможным сокращение набора регрессий по мере развития продукта [32.]. Это еще одна область, в которой может помочь проектирование автоматизированных тестовых наборов, поскольку тестовые наборы будут естественным образом связаны со спецификацией, а трассировка будет встроена.
Стратегии тестирования программного обеспечения
Метод черного ящика
Тестирование по методу черного ящика основано на предположении, что тест не знает содержимого и алгоритмов программного обеспечения, подразумевая только набор входных данных и предсказуемые выходные данные [31.]. Этот метод проводится командой специалистов по тестированию или конечными пользователями. Иногда его также называют функциональным тестом, который не имеет внутреннего механизма системы.
Этот метод включает в себя следующие техники:
- Разделение эквивалентности
Эта методика делит входную область программы на классы эквивалентности, из которых могут быть получены тестовые наборы, что позволяет сократить количество тестовых случаев.
- Анализ граничных значений
Основное внимание уделяется тестированию на границах или там, где выбраны крайние граничные значения. Он включает в себя минимум, максимум, области только внутри / вне границ, значения ошибок и типичные значения.
- Фаззинг
Эта методика подает случайное входное значение в приложение. Он используется для поиска ошибок реализации, используя внедрение некорректных данных в автоматическом или полуавтоматическом режиме.
- Причинно-следственная диаграмма
В этой методике тестирование начинается с создания диаграммы и установления связи между следствием и его причиной.
- Тестирование ортогональных массивов
Эта методика может применяться, когда входная область очень мала, но в то же время слишком велика для проведения исчерпывающего тестирования.
- Метод попарного тестирования
В этой методике тестовые случаи предназначены для выполнения всех возможных дискретных комбинаций каждой пары входных параметров. Ее главная цель – создать набор тестовых случаев, охватывающих все пары.
- Тестирование переходов состояний
Этот тип тестирования полезен для тестирования конечного автомата, а также для навигации по графическому интерфейсу пользователя.
Преимущества [30.]:
- Тестеры могут не иметь никаких специальных знаний конкретного языка программирования.
- Тестирование проводится с точки зрения пользователя.
- Тестирование помогает выявить любые неясности или несоответствия в спецификациях требований.
- Программист и тестер не зависят друг от друга.
Недостатки:
- Тестовые случаи сложно разработать без четких спецификаций.
- Велика вероятность повторения тестов, которые уже выполнены программистом.
- Некоторые части бэкенда вообще не тестируются.
Метод белого ящика
Тестирование белого ящика в основном сфокусировано на внутренней логике и структуре кода. Выполнение этого метода предполагает, что программист обладает методиками, полностью знающими структуру программы. С помощью этой техники можно протестировать каждую ветку и решение в программе [34.]. Метод белого ящика иногда называют структурным тестированием, в котором также проверяется внутренний механизм системы. Тестер знает код и структуру данных, предназначенных для тестирования конкретного метода, который будет выполняться с определенными параметрами. Поэтому, в отличие от тестирования по методу черного ящика, метод белого ящика требует знаний конкретного языка программирования.
Этот метод включает в себя следующие техники (см. рисунок 1):
Рисунок 1. Представление различных видов тестирования по методу белого ящика
1) Ручная имитация работы программы
Это первичное тестирование кода. Специалисты, хорошо владеющие необходимым языком программирования, будут участвовать в контрольных тестах.
2) Разбор кода
В этом процессе тестирования группа технических специалистов подробно разбирает код. Это один из видов техники полуформального изложения.
3) Формальные инспекции
Инспекция – это формальный, эффективный и экономичный метод поиска ошибок в дизайне и коде. Это официальное ревью кода, направленное на выявление всех неисправностей, нарушений и других побочных эффектов.
4) Тестирование потоков управления
Это одна из техник тестирования, основанная на определении путей выполнения кода программного модуля и создания выполняемых тестовых кейсов для покрытия этих путей. Использует поток управления программой в качестве потока управления моделью и предпочитает более простые пути в обход усложненным.
5) Тестирование базового пути
Тестирование базового пути позволяет разработчику тестового примера создать логическую меру полноты процедурного проектирования, а затем использовать эту меру в качестве подхода для определения базового набора путей выполнения.
6) Тестирование потока данных
В этом типе тестирования граф потока управления сопровождается информацией о том, как программные переменные определяются и используются.
- Циклическое тестирование
Сосредоточено исключительно на валидности конструкции цикла.