Файл: Отладка и тестирование программ: основные подходы и ограничения (Определение основных понятий тестирования программных систем).pdf
Добавлен: 01.04.2023
Просмотров: 126
Скачиваний: 2
СОДЕРЖАНИЕ
1. Теоретические основы тестирование и отладки программ
1.1. Определение основных понятий тестирования программных систем
2. Анализ основных подходов и ограничений при отладке и тестировании программ
2.1 Основные подходы и ограничения при тестировании программ
Разработка общего плана проведения отладки, общей методики проверки составленной программы, а также системы необходимых для отладки контрольных примеров.
Проверка разработанных алгоритмов, выбор отлаживающих средств, а также определение контролируемых мест, участков, величин.
Реализация плана отладки для получения на ПК тестовых результатов, необходимых при локализации ошибок; подготовка эталонных результатов для тестов.
Ввод, печать и сверка текста программы.
Получение с помощью транслятора вспомогательных таблиц и проверка их.
Тщательный контроль первых результатов, получаемых по новой программе.
Процесс отладки программ содержит: создание совокупности тестовых эталонных значений и правил, которым должна соответствовать программа по выполняемым функциям, структуре, правилам описания, значениям начальных и соответствующих им результативных данных; статическое тестирование текстов разработанных программ и данных на выполнение всех заданных правил построения и описания без выполнения объектного кода; тестирование программы с ее исполнением в объектном коде и с разными уровнями детализации: детерминированное, стохастическое и тестирование в реальном масштабе времени; диагностику и локализацию причин отклонения результатов тестирования от заданных эталонных значений и правил; разработку изменения программы с целью исключения причин отклонения результатов от эталонных; реализацию корректировки программы, что обеспечивает соответствие программы заданному эталону.
2. Анализ основных подходов и ограничений при отладке и тестировании программ
2.1 Основные подходы и ограничения при тестировании программ
В тестирование ПО входят постановка задачи для теста, проектирование, написание тестов, тестирование тестов, выполнение тестов и изучение результатов тестирования. Важную роль играет проектирование теста. Возможны следующие подходы к стратегии проектирования тестов:
1. Тестирование по отношению к спецификациям (не заботясь о тексте программы).
2. Тестирование по отношению к тексту программы (не заботясь о спецификациях).
Чтобы ориентироваться в стратегиях проектирования тестов, стоит рассмотреть два крайних подхода, находящихся на границах спектра. Следует отметить также, что многие из тех, кто работает в этой области, часто бросаются в одну или другую крайность.
Сторонники первого подхода проектирует тесты, исследуя внешние спецификации или спецификации сопряжения программы или модуля, которые он тестирует. Программа рассматривается как черный ящик. Логика их такова: «Меня не интересует, как выглядит эта программа, и выполнил ли я все команды. Я удовлетворен, если программа будет вести себя так, как указано в спецификациях». То есть в идеале проверить все возможные комбинации и значения на входе.
Сторонники второго подхода проектируют свои тесты, изучая логику программы. Они начинают с того, что стремятся подготовить достаточное число тестов, чтобы каждая команда была выполнена, хотя бы, один раз. Чтобы каждая команда условного перехода выполнялась в каждом направлении хотя бы раз. Их идеал - проверить каждый путь, каждую ветвь алгоритма. При этом не интересуются спецификациями.
Ни одна из этих крайностей не является хорошей стратегией.
Это приводит к следующему принципу тестирования: тестирование - это проблема в значительной степени экономическая. Поскольку исчерпывающее тестирование невозможно, необходимо ограничиться чем-то меньшим. Каждый тест должен давать максимальную отдачу по сравнению с затратами. Эта отдача измеряется вероятностью того, что тест выявит не обнаруженную прежде ошибку. Затраты измеряются временем и стоимостью подготовки, выполнения и проверки результатов теста. Считая, что затраты ограничены бюджетом и графиком, можно утверждать, что искусство тестирования, по существу, представляет собой искусство отбора тестов с максимальной отдачей. Более того, каждый тест должен быть представителем некоторого класса входных значений, чтобы его правильное выполнение создавало убежденность в том, что для определенного класса входных данных программа будет выполняться правильно.
Интеграция модулей
Вторым по важности аспектом тестирования (после проектирования тестов) является последовательность слияния всех модулей в систему или программу. Выбор этой последовательности (должен приниматься на уровне проекта и на ранней стадии) определяет форму, в которую записываются тесты, типы необходимых инструментов тестирования, последовательность программирования модулей, тщательность и экономичность всего этапа тестирования.
Существует несколько подходов, которые могут быть использованы для слияния модулей в более крупные единицы. В большинстве своем они могут рассматриваться как варианты шести основных подходов
Методы тестирования
Большая трудоемкость тестирования и ограниченные ресурсы приводят к необходимости систематизации процесса и методов тестирования. В практике тестирования используются следующие последовательно применяемые методы: статический, детерминированный, стохастический и в реальном масштабе времени.
Статическое тестирование - проводится без использования ЭВМ путем просмотра текста программы после трансляции, проверки правил структурного построения программ и обработки данных. В качестве эталонов используются, во-первых, внутренние спецификации, а, во-вторых, коллективный опыт специалистов-тестировщиков. Применение статического тестирования достаточно эффективно. Для типичных программ, по данным фирмы IBM, можно находить от 30 % до 80 % ошибок логического проектирования и кодирования. Этот метод способствует существенному повышению производительности и надежности программ, позволяет раньше обнаружить ошибки, а значит уменьшить стоимость исправления.
Детерминированное тестирование - это многократное выполнение программы на ЭВМ с использованием определенных, специальным образом подобранных тестовых наборов данных. При детерминированном тестировании контролируются каждая комбинация исходных данных и соответствующие результаты, а также каждое утверждение в спецификации тестируемой программы. Этот метод наиболее трудоемкий, поэтому детерминированное тестирование применяется для отдельных модулей в процессе сборки программы или для небольших и несложных программных комплексов.
Стохастическое тестирование предполагает использование в качестве исходных данных множество случайных величин с соответствующими распределениями. Для сравнения полученных результатов используются также распределения случайных величин. Стохастическое тестирование применяется в основном для обнаружения ошибок, а для диагностики и локализации ошибок приходится переходить к детерминированному тестированию с использованием конкретных значений исходных данных, из области изменения ранее использовавшихся случайных величин. Стохастическое тестирование наилучшим образом подвергается автоматизации путем использования датчиков случайных чисел (генераторов случайных величин) и применяется для комплексного тестирования ППП.
Тестирование в реальном масштабе времени осуществляется для ППП, предназначенных для работы в системах реального времени. В процессе такого тестирования проверяются результаты обработки исходных данных с учетом времени их поступления, длительности и приоритетности обработки, динамики использования памяти и взаимодействия с другими программами. При обнаружении отклонения результатов выполнения программ от ожидаемых для локализации ошибок, приходится фиксировать время и переходить к детерминированному тестированию.
Каждый из рассмотренных методов тестирования не исключает применения другого метода, скорее наоборот, требование к повышению качества ППП предполагает необходимость подвергать их различным методам тестирования и их сочетаниям, в зависимости от сложности ППП и области его применения.
Восходящее тестирование
При восходящем подходе программа собирается и тестируется снизу вверх. Только модули самого нижнего уровня («терминальные» модули; модули, не вызывающие других модулей) тестируются изолированно, автономно. После того как тестирование этих модулей завершено, вызов их должен быть так же надежен, как вызов встроенной функции языка или оператор присваивания. Затем тестируются модули, непосредственно вызывающие уже проверенные. Эти модули более высокого уровня тестируются не автономно, а вместе с уже проверенными модулями более низкого уровня. Процесс повторяется до тех пор, пока не будет достигнута вершина. Здесь завершаются и тестирование модулей, и тестирование сопряжений программы.
При восходящем тестировании для каждого модуля необходим драйвер: нужно подавать тесты в соответствии с сопряжением тестируемого модуля. Одно из возможных решений - написать для каждого модуля небольшую ведущую программу. Тестовые данные представляются как «встроенные» в эту программу переменные и структуры данных, и она многократно вызывает тестируемый модуль, с каждым вызовом передавая ему новые тестовые данные. Имеется и лучшее решение: воспользоваться программой тестирования модулей - это инструмент тестирования, позволяющий описывать тесты на специальном языке и избавляющий от необходимости писать драйверы.
Нисходящее тестирование
При нисходящем подходе программа собирается и тестируется сверху вниз. Изолировано тестируется только головной модуль. После того как тестирование этого модуля завершено, с ним соединяются (например, редактором связей) один за другим модули, непосредственно вызываемые им, и тестируется полученная комбинация. Процесс повторяется до тех пор, пока не будут собраны и проверены все модули.
При этом подходе возникают два вопроса: что делать, когда тестируемый модуль вызывает модуль более низкого уровня (которого в данный момент еще не существует), и как подаются тестовые данные. Ответ на первый вопрос состоит в том, что для имитации функций недостающих модулей программируются модули-заглушки, которые моделируют функции отсутствующих модулей. Фраза «напишите заглушку» часто встречается в описании этого подхода, но она способна ввести в заблуждение, поскольку задача написания «заглушки» может оказаться трудной. Ведь заглушка редко сводится просто к оператору RETURN, поскольку вызывающий модуль обычно ожидает от нее выходных параметров. В таких случаях в заглушку встраивают фиксированные выходные данные, которые она всегда и возвращает. Иногда это оказывается неприемлемым, так как вызывающий модуль может рассчитывать, что результат вызова зависит от входных данных. Поэтому в некоторых случаях заглушка должна быть довольно изощренной, приближаясь по сложности к модулю, который она пытается моделировать.
Интересен и второй вопрос: в какой форме готовятся тестовые данные и как они передаются программе? Если бы головной модуль содержал все нужные операции ввода и вывода, ответ был бы простым: тесты пишутся в виде обычных для пользователей внешних данных и передаются программе через выделенные ей устройства ввода. Но так случается редко. В хорошо спроектированной программе физические операции ввода-вывода выполняются на нижних уровнях структуры, поскольку физический ввод-вывод - это абстракция довольно низкого уровня. Поэтому для того, чтобы решить проблему экономически эффективно, модули добавляются не в строго нисходящей последовательности (все модули одного горизонтального уровня, затем модули следующего уровня), а таким образом, чтобы обеспечить функционирование операций физического ввода-вывода как можно быстрее. Когда эта цель достигнута, нисходящее тестирование получает значительное преимущество: все дальнейшие тесты готовятся в той же форме, которая рассчитана на пользователя.
Нисходящий метод имеет как достоинства, так и недостатки, по сравнению с восходящим. Его достоинство заключается в том, что этот метод совмещает тестирование модуля, тестирование сопряжений и частично тестирование внешних функций. С этим связано и другое его достоинство - когда модули ввода-вывода уже подключены, тесты можно готовить в удобном виде.
Нисходящий подход выгоден и в том случае, когда есть сомнения относительно осуществимости программы в целом или если в проекте программы могут оказаться серьезные дефекты.