Автор работы: s*********@gmail.com, 27 Ноября 2011 в 16:55, курсовая работа
Качество ПС стало основой их конкурентоспособности и возможности широкого применения. Номенклатура и требуемые значения показателей качества определяются прежде всего функциональным назначением конкретного ПС. Это приводит к широкому спектру показателей качества в спецификациях требований.
Еще одна причина, не упомянутая в анализируемых исследованиях, но которая могла бы стать объектом дальнейшего исследования по этой теме, заключается в том, что участвующие разработчики нередко превращаются в рецензентов, анализируя код других программистов, которые используют их код в последующих разработках. Это важно в тех случаях, когда новый код может повлиять на созданные ими функции или на другую связанную с ними функциональность. В силу этого разработчики первоначального кода, как правило, стремятся избежать любых упреков в недостаточно высоком качестве.
Глава
II.Тестированиещпрограммныхщпр
В философском определении термин «качество»
означает: «Качество есть в первую очередь
тождественная с бытием определенность,
так что нечто перестает быть тем, что
оно есть, когда оно теряет качество»
(Гегель)
Тестирование программного обеспечения
охватывает целый ряд видов деятельности,
весьма аналогичный последовательности
процессов разработки программного обеспечения.
Сюда входят постановка задачи для теста,
проектирование, написание тестов, тестирование
тестов и, наконец, выполнение тестов и
изучение результатов тестирования. Решающую
роль играет проектирование теста. Возможен
целый спектр подходов к выработке философии,
или стратегии проектирования тестов.
Чтобы ориентироваться в стратегиях проектирования
тестов, стоит рассмотреть два крайних
подхода, находящихся на границах спектра.
Следует отметить также, что многие из
тех, кто работает в этой области, часто
бросаются в одну или другую крайность.
Сторонник (или сторонница) подхода, соответствующего
левой границе спектра, проектирует свои
тесты, исследуя внешние спецификации
или спецификации сопряжения программы
или модуля, которые он тестирует. Программу
он рассматривает как черный ящик. Позиция
его такова: «Меня не интересует, как выглядит
эта программа и выполнил ли я все команды
или все пути. Я буду удовлетворен, если
программа будет вести себя так, как указано
в спецификациях». Его идеал — проверить
все возможные комбинациищищзначениящнащвходе
Приверженец подхода, соответствующего
другому концу спектра, проектирует свои
тесты, изучая логику программы. Он начинает
с того, что стремится подготовить достаточное
число тестов для того, чтобы каждая команда
была выполнена по крайней мере один раз.
Если он немного более искушен, то проектирует
тесты так, чтобы каждая команда условного
перехода выполнялась в каждом направлении
хотя бы раз. Его идеал — проверить каждый
путь, каждую ветвь алгоритма. При этом
его совсем (или почти
Ни одна из этих крайностей не является
хорошей стратегией. Читатель, однако,
уже, вероятно, заметил, что первая из них,
а именно та, в соответствии с которой
программа рассматривается как черный
ящик, предпочтительней. К сожалению, она
страдает тем недостатком, что совершенно
неосуществима. Рассмотрим попытку тестирования
тривиальной программы, получающей на
входе три числа и вычисляющей их среднее
арифметическое. Тестирование этой программы
для всех значений входных данных невозможно.
Даже для машины с относительно низкой
точностью вычислений количество тестов
исчислялось бы миллиардами. Даже имей
мы вычислительную мощность, достаточную
для выполнения всех тестов в разумное
время, мы потратили бы на несколько порядков
больше времени для того, чтобы эти тесты
подготовить, а затем проверить. Такие
программы, как системы реального времени,
операционные системы и программы управления
данными, которые сохраняют «память» о
предыдущих входных данных, еще хуже. Нам
потребовалось бы тестировать программу
не только для каждого входного значения,
но и для каждой последовательности, каждой
комбинации входных данных. Поэтому исчерпывающее
тестирование для всех входных данных
любой разумной программы неосуществимо.
Эти рассуждения приводят ко второму фундаментальному
принципу тестирования: тестирование
— проблема в значительной степени экономическая.
Поскольку исчерпывающее тестирование
невозможно, мы должны ограничиться чем-то
меньшим. Каждый тест должен давать максимальную
отдачу по сравнению с нашими затратами.
Эта отдача измеряется вероятностью тою,
что тест выявит не обнаруженную прежде
ошибку. Затраты измеряются временем и
стоимостью подготовки, выполнения и проверки
результатов теста. Считая, что затраты
ограничены бюджетом и графиком, можно
утверждать, что искусство тестирования,
по существу, представляет собой искусство
отбора тестов с максимальной отдачей.
Более того, каждый тест должен быть представителем
некоторого класса входных значений, так
чтобы его правильное выполнение создавало
у нас некоторую убежденность в том, что
для определенного класса входных данных
программа будет выполняться правильно.
Это обычно требует некоторого знания
алгоритма и структуры программы, и мы,
таким образом, смещаемся к правому концу
спектра.
2.Интеграция модулей.
Вторым по важности аспектом
тестирования (после проектирования
тестов) является последовательность
слияния всех модулей в
Имеется большой выбор возможных подходов,
которые могут быть использованы для слияния
модулей в более крупные единицы. В большинстве
своем они могут рассматриваться как варианты
шести основных подходов, описанных в
следующих шести разделах. Сразу же за
ними идет раздел, где предложенные подходы
сравниваются по их влиянию на надежность
программного обеспечения.
3.Восходящее, нисходящее тестирование.
При восходящем подходе программа собирается
и тестируется снизу вверх. Только модули
самого нижнего уровня («терминальные»
модули; модули, не вызывающие других модулей)
тестируются изолированно, автономно.
После того как тестирование этих модулей
завершено, вызов их должен быть так же
надежен, как вызов встроенной функции
языка или оператор присваивания. Затем
тестируются модули, непосредственно
вызывающие уже проверенные. Эти модули
более высокого уровня тестируются не
автономно, а вместе с уже проверенными
модулями более низкого уровня. Процесс
повторяется до тех пор, пока не будет
достигнута вершина. Здесь завершаются
и тестирование модулей, и тестирование
сопряжениищпрограммы.
При восходящем тестировании для каждого
модуля необходим драйвер: нужно подавать
тесты в соответствии с сопряжением тестируемого
модуля. Одно из возможных решении — написать
для каждого модуля небольшую ведущую
программу. Тестовые данные представляются
как «встроенные» непосредственно в эту
программу переменные и структуры данных,
и она многократно вызывает тестируемый
модуль, с каждым вызовом передавая ему
новые тестовые данные. Имеется и лучшее
решение: воспользоваться программой
тестирования модулей — это инструмент
тестирования, позволяющий описывать
тесты на специальном языке и избавляющий
от необходимостищписатьщдрайверы.
При этом подходе немедленно возникает
два вопроса: что делать, когда тестируемый
модуль вызывает модуль более низкого
уровня (которого в данный момент еще не
существует), и как подаются тестовые данные.
Ответ на первый вопрос состоит в том,
что для имитации функций недостающих
модулей программируются модули-заглушки»,
которые моделируют функции отсутствующих
модулей. Фраза «просто напишите заглушку»
часто встречается в описании этого подхода,
но она способна ввести в заблуждение,
поскольку задача написания заглушки»
может оказаться трудной. Ведь заглушка
редко сводится просто к оператору RETURN,
поскольку вызывающий модуль обычно ожидает
от нее выходных параметров. В таких случаях
в заглушку встраивают фиксированные
выходные данные, которые она всегда и
возвращает. Это иногда оказывается неприемлемым,
так как вызывающий модуль может рассчитывать,
что результат вызова зависит от входных
данных. Поэтому в некоторых случаях заглушка
должна быть довольно изощренной, приближаясь
по сложности к модулю,щкоторыйщонащпытаетсящм
Интересен и второй вопрос: «в какой форме
готовятся тестовые данные и как они передаются
программе?» Если бы головной модуль содержал
все нужные операции
Тесты пишутся в виде обычных для пользователей
внешних данных и передаются программе
через выделенные ей устройства ввода.
Так, однако, случается редко. В хорошо
спроектированной программе физические
операции ввода-вывода выполняются на
нижних уровнях структуры, поскольку физический
ввод-вывод — абстракция довольно низкого
уровня. Поэтому для того, чтобы решить
проблему экономически эффективно, модули
добавляются не в строго нисходящей последовательности
(все модули одного горизонтального уровня,
затем модули следующего уровня), а таким
образом, чтобы обеспечить функционирование
операций физического ввода-вывода как
можно быстрее. Когда эта цель достигнута,
нисходящее тестирование получает значительное
преимущество: все дальнейшие тесты готовятся
в той же форме, которая рассчитана на
пользователя.
Остается еще один вопрос: в какой форме
пишутся тесты до тех пор, пока не будет
достигнута эта цель? Ответ: они включаются
в некоторые из заглушек.
Нисходящий метод имеет как достоинства,
так и недостатки по сравнению с восходящим.
Самое значительное достоинство — в том,
что этот метод совмещает тестирование
модуля, тестирование сопряжении и частично
тестирование внешних функций. С этим
же связано другое его достоинство — когда
модули ввода-вывода уже подключены, тесты
можно готовить в удобном виде. Нисходящий
подход выгоден также в том случае, когда
есть сомнения относительно осуществимости
программы в целом или если в проекте программы
могут оказаться серьезные дефекты.
Преимуществом нисходящего подхода очень
часто считают отсутствие необходимости
в драйверах; вместо драйверов вам просто
следует написать «заглушки». Как читатель
сейчас уже, вероятно, понимает, это преимущество
спорно.
Нисходящий метод тестирования имеет,
к сожалению, некоторые недостатки. Основным
из них является тот, что модуль редко
тестируется досконально сразу после
его подключения. Дело в том, что основательное
тестирование некоторых модулей может
потребовать крайне изощренных заглушек.
Программист часто решает не тратить массу
времени на их программирование, а вместо
этого пишет простые заглушки и проверяет
лишь часть условий в модуле. Он, конечно,
собирается вернуться и закончить тестирование
рассматриваемого модуля позже, когда
уберет заглушки. Такой план тестирования
определенно не лучшее решение, поскольку
об отложенныхщусловияхщчастощзабы
Второй тонкий недостаток нисходящего
подхода состоит в том, что он может породить
веру в возможность начать программирование
и тестирование верхнего уровня программы
до того, как вся программа будет полностью
спроектирована. Эта идея на первый взгляд
кажется экономичной, но обычно дело обстоит
совсем наоборот. Большинство опытных
проектировщиков признает, что проектирование
программы — процесс итеративный. Редко
первый проект оказывается совершенным.
Нормальный стиль проектирования структуры
программы предполагает по окончании
проектирования нижних уровней вернуться
назад и подправить верхний уровень, внеся
в него некоторые усовершенствования
или исправляя ошибки, либо иногда даже
выбросить проект и начать все сначала,
потому что разработчик внезапно увидел
лучший подход. Если же головная часть
программы уже запрограммирована и оттестирована,
то возникает серьезное сопротивление
любым улучшениям ее структуры. В конечном
итоге за счет таких улучшений обычно
можно сэкономить больше, чем те несколько
дней или недель, которые рассчитывает
выиграть проектировщик, приступая к программированию
4.Методы тестирования программного обеспечения: метод большого скачка, метод Сандвича, модифицированный метод Сандвича.
Методщбольшогощскачка.
Метод большого скачка по сравнению с
другими подходами имеет много недостатков
и мало достоинств. Заглушки и драйверы
необходимы для каждого модуля. Модули
не интегрируются до самого последнего
момента, а это означает, что в течение
долгого времени серьезные ошибки в сопряжениях
могут остаться необнаруженными. Метод
большого скачка значительно
И все же большой скачок не всегда нежелателен.
Если программа мала и хорошо спроектирована,
он может оказаться приемлемым. Однако
для крупных программ метод большого скачка
обычно губителен. Метод
При использовании этого метода одновременно
начинают восходящее и нисходящее тестирование,
собирая программу как снизу, так и сверху
и встречаясь в конце концов где-то в середине.
Точка встречи зависит от конкретной тестируемой
программы и должна быть заранее определена
при изучении ее структуры. Например, если
разработчик может представить свою систему
в виде уровня прикладных модулей, затем
уровня модулей обработки запросов, затем
уровня примитивных функций, то он может
решить применять нисходящий метод на
уровне прикладных модулей (программируя
заглушки вместо модулей обработки запросов),
а на остальных уровнях применить восходящий
метод.
Применение метода сандвича - это разумный
подход к интеграции больших программ,
таких, как операционная система или пакет
прикладных программ.
Метод сандвича сохраняет такое достоинство
нисходящего и восходящего подходов, как
начало интеграции системы на самом раннем
этапе. Поскольку вершина программы вступает
в строй рано, мы, как в нисходящем методе,
уже на раннем этапе получаем работающий
каркас программы. Поскольку нижние уровни
программы создаются восходящим методом,
снимаются те проблемы нисходящего метода,
которые были связаны с невозможностью
тестировать
При тестировании методом сандвича возникает
та же проблема, что и при нисходящем подходе,
хотя здесь она стоит не так остро. Проблема
эта в том, что невозможно досконально
тестировать отдельные модули. Восходящий
этап тестирования по методу сандвича
решает эту проблему для модулей нижних
уровней, но она может по-прежнему оставаться
открытой для нижней половины верхней
части программы. В модифицированном методе
сандвича нижние уровни также тестируются
строго снизу вверх. А модули верхних уровней
сначала тестируются изолированно, а затем
собираются нисходящим методом. Таким
образом, модифицированный метод сандвича
также представляет собой компромисс
между восходящим и нисходящим подходами.
Информация о работе Программное обеспечение управления качеством