Главная | Обратная связь | Поможем написать вашу работу!
МегаЛекции

Тестирование программного обеспечения: основные цели, особенности и методы.




 

.1 Общие понятия

 

История тестирования программного обеспечения отражает эволюцию разработки самого программного обеспечения. В течение длительного времени разработка программного обеспечения уделяла основное внимание крупномасштабным научным программам, а также программам министерства обороны, связанным с системами корпоративных баз данных, которые проектировались на базе универсальной ЭВМ или миникомпьютера. Тестовые сценарии записывались на бумагу. С их помощью проверялись целевые потоки управления, вычисления сложных алгоритмов и манипулирование данными. Окончательный набор тестовых процедур мог эффективно протестировать всю систему полностью. Тестирование обычно начиналось лишь после завершения плана-графика проекта и выполнялось тем же персоналом.

«Тестирование - процесс, подтверждающий правильность программы и демонстрирующий, что ошибок в программе нет.» Основной недостаток подобного определения заключается в том, что оно совершенно неправильно; фактически это почти определение антонима слова «тестирование». Люди с некоторым опытом программирования уже, вероятно, понимает, что невозможно продемонстрировать отсутствие ошибок в программе. Поэтому определение описывает невыполнимую задачу, а так как тестирование зачастую все же выполняется с успехом, по крайней мере с некоторым успехом, то такое определение логически некорректно. Правильное определение тестирования таково: Тестирование - процесс выполнения программы с намерением найти ошибки.

Невозможно гарантировать отсутствие ошибок в нетривиальной программе; в лучшем случае можно попытаться показать наличие ошибок. Если программа правильно ведет себя для солидного набора тестов, нет основании утверждать, что в ней нет ошибок; со всей определенностью можно лишь утверждать, что не известно, когда эта программа не работает. Конечно, если есть причины считать данный набор тестов способным с большой вероятностью обнаружить все возможные ошибки, то можно говорить о некотором уровне уверенности в правильности программы, устанавливаемом этими тестами.

Большинство людей, поставив цель (например, показать, что ошибок нет), ориентируется в своей деятельности на достижение этой цели. Тестировщик подсознательно не позволит себе действовать против цели, т. е. подготовить тест, который выявил бы одну из оставшихся в программе ошибок. Поскольку мы все признаем, что совершенство в проектировании и кодировании любой программы недостижимо и поэтому каждая программа содержит некоторое количество ошибок, самым плодотворным применением тестирования будет найти некоторые из них. Если мы хотим добиться этого и избежать психологического барьера, мешающего нам действовать против поставленной цели, наша цель должна состоять в том, чтобы найти как можно больше ошибок.

Появление персональных компьютеров способствовало стандартизации этой отрасли, поскольку приложения стали изначально создаваться для работы с общей операционной системой. Внедрение персональных компьютеров открыло новую эру и привело к быстрому и бурному росту коммерческих разработок. Коммерческие приложения жестко боролись за первенство и выживание. Пользователи компьютеров принимали выжившее программное обеспечение как стандарты defacto. Пакетная обработка заменялась системами, работающими в реальном времени.

Тестирование систем реального времени потребовало другого подхода к проектированию тестирования из-за того, что рабочие потоки могли вызываться в любом порядке. Эта особенность привела к появлению огромного количества процедур тестирования, способных поддержать бесконечное число перестановок и сочетаний.

Сформулируем основополагающий вывод:

· Если ваша цель - показать отсутствие ошибок, то вы их найдете не слишком много.

· Если же ваша цель - показать наличие ошибок, вы найдете значительную их часть.

Причиной многих несчастий разработчиков являются программные ошибки, из-за которых на их многострадальные головы сваливаются и давно просроченные проекты, и бессонные ночи. Ошибки могут сделать жизнь разработчиков действительно несчастной, потому что, достаточно нескольким ошибкам вкрасться в их программы, как заказчики прекращают этими программами пользоваться, а сами они могут потерять работу.

Надежность невозможно внести в программу в результате тестирования, она определяется правильностью этапов проектирования. Наилучшее решение проблемы надежности - с самого начала не допускать ошибок в программе.

Однако вероятность того, что удастся безупречно спроектировать большую программу, бесконечно мала. Роль тестирования состоит как раз в том, чтобы определить местонахождение немногочисленных ошибок, оставшихся в хорошо спроектированной программе. Попытки с помощью тестирования достичь надежности плохо спроектированной программы совершенно бесплодны.

Долгое время ошибки рассматривали как простые неприятности. Ничто не может быть дальше от истины. Всем программистам известны компании, которые закрылись только потому, что выпускали программные продукты, совершенно непригодные к использованию из-за обилия ошибок. В связи со всеобщей компьютеризацией, все шире и шире захватывающей такие важные области, как управление системами жизнеобеспечения, медицинские приборы и сверхдорогую компьютерную аппаратуру, над ошибками больше нельзя просто посмеиваться или рассматривать их как нечто имеющее значение только на этапах разработки.

Тестирование оказывается довольно необычным процессом (вот почему оно и считается трудным), так как этот процесс разрушительный. Ведь цель проверяющего (тестировщика) - заставить программу сбиться. Он доволен, если это ему удается; если же программа на его тесте не сбивается, он не

удовлетворен.

Еще одна причина, по которой трудно говорить о тестировании - это тот факт, что о нем известно очень немногое. Если сегодня мы располагаем 5% тех знании о проектировании и собственно программировании (кодировании), которые будут у нас к 2000 г., то о тестировании нам известно менее 1%.

 

1.2 Основные определения

 

Хотя в тестировании можно выделить несколько различных процессов, такие термины, как тестирование, отладка, доказательство, контроль и испытание, часто используются как синонимы и, к сожалению, для разных людей имеют разный смысл. Хотя стандартных, общепринятых определений этих терминов нет, попытка сформулировать их была предпринята на симпозиуме по тестированию программ. Классификацию различных форм тестирования я начну с того, что дам эти определения, слегка дополнив и расширив их список.

Тестирование (testing), как мы уже выяснили,-процесс выполнения программы (или части программы) с намерением (или целью) найти ошибки.

Доказательство (proof) - попытка найти ошибки в программе безотносительно к внешней для программы среде. Большинство методов доказательства предполагает формулировку утверждений о поведении программы и затем вывод и доказательство математических теорем о правильности программы. Доказательства могут рассматриваться как форма тестирования, хотя они и не предполагают прямого выполнения программы. Многие исследователи считают доказательство альтернативой тестированию - взгляд во многом ошибочный.

Контроль (verification) - попытка найти ошибки, выполняя программу в тестовой, или моделируемой, среде.

Испытание (validation) - попытка найти ошибки, выполняя программу в заданной реальной среде.

Аттестация (certification) - авторитетное подтверждение правильности программы, аналогичное аттестации электротехнического оборудования Underwriters Laboratories. При тестировании с целью аттестации выполняется сравнение с некоторым заранее определенным стандартом.

Отладка (debugging) не является разновидностью тестирования. Хотя слова «отладка» и «тестирование» часто используются как синонимы, под ними подразумеваются разные виды деятельности. Тестирование - деятельность, направленная на обнаружение ошибок; отладка направлена на установление точной природы известной ошибки, а затем - на исправление этой ошибки. Эти два вида деятельности связаны - результаты тестирования являются исходными данными для отладки.

Тестирование модуля, или автономное тестирование (module testing, unit testing) - контроль отдельного программного модуля, обычно в изолированной среде (т. е. изолированно от всех остальных модулей). Тестирование модуля иногда включает также математическое доказательство.

Тестирование сопряжении (integration testing) - контроль сопряжении между частями системы (модулями, компонентами, подсистемами).

Тестирование внешних функций (external function testing) - контроль внешнего поведения системы, определенного внешними спецификациями.

Комплексное тестирование (system testing) - контроль и/или испытание системы по отношению к исходным целям. Комплексное тестирование является процессом контроля, если оно выполняется в моделируемой среде, и процессом испытания, если выполняется в среде реальной, жизненной.

Тестирование приемлемости (acceptance testing) - проверка соответствия программы требованиям пользователя.

Тестирование настройки (installation testing) - проверка соответствия каждого конкретного варианта установки системы с целью выявить любые ошибки, возникшие в процессе настройки системы.

 

2.
Тестирование ПО

 

.1 Классификация видов тестирования

 

Тестирование ПО - это процесс его исследования с целью получения информации о качестве. Целью тестирования является выявление дефектов в ПО. С помощью тестирования нельзя доказать отсутствие дефектов и корректность функционирования анализируемой программы. Тестирование сложных программных продуктов является творческим процессом, не сводящимся к следованию строгим и четким процедурам.

Тестирование программного обеспечения охватывает целый ряд видов деятельности, весьма аналогичный последовательности процессов разработки программного обеспечения. Сюда входят постановка задачи для теста, проектирование, написание тестов, тестирование тестов и, наконец, выполнение тестов и изучение результатов тестирования. Решающую роль играет проектирование теста.

Состав и содержание документации, сопутствующей процессу тестирования, определяется зарубежным стандартом IEEE 829-2008 Standard for Software Test Documentation.

Существует несколько оснований, по которым принято производить классификацию видов тестирования.

. По объекту тестирования

· Функциональное тестирование (functional testing)

· Нагрузочное тестирование (performance/load/stress testing)

· Тестирование удобства использования (usability testing)

· Тестирование интерфейса пользователя (UI testing)

· Тестирование безопасности (security testing)

· Тестирование локализации (localization testing)

· Тестирование совместимости (compatibility testing)

. По знаниям о тестируемой системе

· Тестирование методом «черного ящика» (black box)

· Тестирование методом «белого ящика» (white box)

· Тестирование методом «серого ящика» (grey box)

. По уровню автоматизации

· Ручное тестирование (manual testing)

· Автоматизированное тестирование (automated testing)

. По степени изолированности

· Модульное тестирование (unit testing)

· Интеграционное тестирование (integration testing)

· Системное тестирование (system testing)

. По уровню готовности

· Альфа-тестирование (alpha testing)

· Бета-тестирование (beta testing)

· Приемосдаточные испытания (acceptance testing)

 

.2 Функциональное тестирование и тестирование качества

 

Функциональное тестирование проводится для проверки выполнения системой функциональных требований.

Нагрузочное тестирование проводится для анализа работы системы при различных уровнях нагрузки (большие объемы данных или количество пользователей). С помощью нагрузочного тестирования можно экспериментально определить требования к ресурсам, масштабируемость и надежность созданной системы. С точки зрения заказчика системы, нагрузочное тестирование является одним из способов проверки работы системы в условиях, приближенных к реальным.

Основными показателями производительности информационной системы, измеряемыми в ходе нагрузочного тестирования, являются:

· Время отклика (время выполнения операции)

· Число операций, выполняемых в единицу времени (например, transactions per second, TPS).

Основным результатом нагрузочного тестирования являются измерения производительности информационной системы, которые могут быть использованы для локализации узких мест и последующей оптимизации. В процессе нагрузочного тестирования может быть построена «кривая деградации» - график, показывающий зависимость производительности системы (например, в единицах времени отклика) от рабочей нагрузки (например, от числа виртуальных пользователей).

Стрессовое (stress) тестирование проводится в условиях недостаточных системных ресурсов и позволяет оценить уровень надежности работы системы под нагрузкой.

Тестирование удобства использования имеет целью оценить приемлемость пользовательского интерфейса приложения (время, затраченное на достижение цели, полученный результат, легкость доступа к нужной информации, интерпретация ответов системы и т.д.)

Чтобы охватить все аспекты удобства использования, наряду со специалистами по обеспечению качества в этом виде тестирования могут принимать участие специалисты по маркетингу и психологи, а также будущие пользователи системы. В процессе тестирования пользователям под руководством модератора предлагается решить с использованием системы ряд задач. Для последующего анализа результатов тестирования необходима четкая фиксация всех происходящих событий: использование клавиатуры и мыши, выражение лица респондента, переходы между экранами, речь модератора и респондента.

Тестирование интерфейса пользователя (UI testing) предполагает проверку соответствия ПО требованиям к графическому интерфейсу пользователя. Различают следующие виды тестирования графического интерфейса пользователя:

· Тестирование на соответствие стандартам графических интерфейсов;

· Тестирование с различными разрешениями экрана;

· Тестирование локализованных версий: проверка длины названий элементов интерфейса и т.п.;

· Тестирование графического интерфейса пользователя на различных целевых устройствах (для мобильных приложений, возможно с использованием эмуляторов).

В ходе тестирование безопасности (security testing) проводится оценка уязвимости системы по отношению к атакам. Тестирование безопасности проверяет фактическую реакцию защитных механизмов, встроенных в систему, на попытки их взлома и обхода. В ходе тестирования безопасности испытатель играет роль потенциального нарушителя и пытается проверить следующие аспекты безопасности системы:

· Тестирование механизмов контроля доступа - помогает обнаружить дефекты, в результате которых пользователи могут получать несанкционированный доступ к объектам и функциям приложения;

· Тестирование авторизации пользователей - выявляет дефекты, связанные с авторизацией отдельных пользователей и г8рупп пользователей и с проверкой их подлинности;

· Тестирование процедур проверки корректности ввода - имеет целью выявление ошибок в процедурах проверки данных, поступающих в систему извне;

· Тестирование криптографических механизмов защиты - используется для выявления дефектов, связанных с шифрованием и расшифрованием данных, использованием цифровых подписей и проверкой целостности данных;

· Тестирование правильности обработки ошибок - включает в себя проверку таких аспектов, как вывод на экран фрагментов кода при ощибке, влияние ошибок на работу всего приложения, анализ ошибок в коде их обработки;

· Тестирование на переполнение буфера - выявляет выход за границы буферов при обработке данных;

· Тестирование конфигурации сервера - помогает обнаружить ошибки, связанные с раскрытием конфигурации аппаратных и программных средств, а также с некорректными настройками параметров безопасности серверного ПО.

Задача проектировщика системы состоит в том, чтобы сделать затраты на организацию атаки выше, чем цена получаемой в результате информации.

В процессе тестирования локализации (localization testing) проверяются различные аспекты, связанные с региональными особенностями (проверка работы различных языковых версий, систем измерений, форматов дат, нумерации дней недели, порядка сортировки и т.д.)

Тестирование совместимости (compatibility testing) - проверка совместимости системы с различными вариантами программно-аппаратного окружения (операционными системами, различными браузерами, сетевым ПО, СУБД, сторонним ПО, аппаратной платформой).

 

.
Виды и уровни тестирования

 

.1 Виды тестирования

 

Выделяют три уровня тестирования: модульное, интеграционное и системное.

Модульное тестирование - тестирование, имеющее целью проверить работоспособность отдельных модулей (функции или класса). Модульное тестирование обычно выполняется независимо для каждого программного модуля и является, пожалуй, наиболее распространенным видом тестирования, особенно для систем малых и средних размеров. В качестве критерия полноты используется процент покрытия тестами ключевых элементов модуля (операторы, ветви логических условий и т.д.). Стандарт IEEE 1008-1987 определяет содержание фаз процесса модульного тестирования.

Модульные тесты проверяют, что определенные воздействия на модуль приводят к желаемому результату. Как правило. Модульные тесты создаются с использованием метода «белого ящика». При наличии зависимостей тестируемого модуля от других модулей вместо них используются так называемые mock-объекты, предоставляющие фиктивную реализацию их интерфейсов. С использованием mock-объектов могут быть протестированы такие аспекты функционирования, которые невозможно проверить с использованием реальных зависимых модулей. Существуют специальные библиотеки (например, Moq), упрощающие задачу создания mock-объектов. В работе (Месарош Дж. «Шаблоны тестирования xUnit. Рефакторинг кода тестов») описываются наиболее удачные подходы к организации модульного тестирования.

Модульное тестирование позволяет программистам безопасно проводить рефакторинг, будучи уверенными, что измененный модуль по-прежнему работает корректно. Модульные тесты могут использоваться в качестве спецификации, так как при тестировании фактически проверяется их ожидаемое поведение.

Для большинства популярных языков программирования высокого уровня существуют инструменты и библиотеки модульного тестирования (например, инструменты семейства xUnit: NUnit, JUnit, CppUnit).

Интеграционное тестирование (integration testing) - одна из фаз тестирования ПО, при котором отдельные программные модули объединяются и тестируются в комплексе. Обычно интеграционное тестирования проводится после модульного тестирования и предшествует системному тестированию. Целью данного вида тестирования является нахождение проблем взаимодействия модулей взаимодействия модулей (компонент, подсистем). При наличии резерва времени на данное стадии тестирование ведется итерационно, с постепенным подключением последующих подсистем. Тестирование выполняется через интерфейс модулей с использованием метода «черного ящика».

Существует несколько стратегий проведения интеграционного тестирования, которые основываются на знаниях об архитектуре системы.

Монолитное тестирование предполагает, что отдельные компоненты системы серьезного тестирования не проходили. Система проверяется вся в целом после разработки всех модулей. Этот подход не следует путать с системным тестированием. Несмотря на то что при монолитном тестировании проверяется работа всей системы в целом, основная задача этого тестирования - определить проблемы взаимодействия отдельных модулей системы. Основные недостатки монолитного тестирования заключаются в сложности выявления источников ошибок, а также в сложности автоматизации данного вида тестирования. На практике чаще всего в различных частях проекта применяются все рассмотренные в предыдущем разделе методы в совокупности. Каждый модуль тестируют по мере готовности отдельно, а потом включают в уже готовую композицию. Для одних частей тестирование получается нисходящим, для других - восходящим.

Ранее рассматривался подход к организации интеграционного тестирования на основе применения систем непрерывной интеграции, использование которых позволяет быстро выявлять проблемы взаимодействия модулей.

Системное тестирование - это тестирование полной, интегрированной системы с целью проверки ее соответствия системным требованиям и показателям качества. Системные тесты учитывают такие аспекты системы, как устойчивость в работе, производительность, соответствие системы ожиданиям пользователя и т.п. Для определения полноты системного тестирования оцениваются выполнение всех возможных сценариев работы (как штатных, так и нештатных), различные методы взаимодействия системы с внешней средой и т.д. Системное тестирование, как правило, использует метод «черного ящика».

 

3.2 Уровни тестирования

 

· Приемочное тестирование (Acceptance/ qualification testing).

Проверяет поведение системы на предмет удовлетворения требований заказчика. Это возможно в том случае, если заказчик берет на себя ответственность, связанную с проведением таких работ, как сторона «принимающая» программную систему, или специфированы типовые задачи, успешная проверка (тестирование) которых позволяет говорить об удовлетворении требований заказчика.

Такие тесты могут проводиться как с привлечением разработчиков системы, так и без них.

· Установочное тестирование (Installation testing).

Из названия следует, что данные тесты проводятся с целью проверки процедуры инсталляции системы в целевом окружении.

· Альфа- и бета-тестирование (Alpha and Beta testing).

Перед тем, как выпускается программное обеспечение, как минимум, оно должно проходить стадии альфа (внутреннее пробное использование) и бета (пробное использование с привлечением отобранных внешних пользователей) версий. Отчеты об ошибках, поступающие от пользователей этих версий продукта, обрабатываются в соответствии с определенными процедурами, включающими подтверждающие тесты (любого уровня), проводимые специалистами группы разработки. Данный вид тестирования не может быть заранее спланирован.

Альфа-тестирование - использование незавершенной (альфа) версии ПО, в которой реализована не вся функциональность, запланированная для данной версии продукта. При альфа-тестировании производится имитация реальной работы с системой (выполняется штатными разработчиками) либо реальная работа с системой потенциальных пользователей (заказчика) с целью выявления ошибок в работе реализованных модулей и функций для их последующего устранения перед бета-тестированием. Чаще всего альфа-тестирование проводится на ранней стадии разработки продукта, но в некоторых случаях может применяться для законченного продукта в качестве внутреннего приемочного тестирования. Иногда альфа-тестирование выполняется под отладчиком или с использованием окружения, которое помогает быстро выявлять найденные ошибки. Обнаруженные ошибки могут быть переданы тестировщикам для дополнительного исследования.

Бета-тестирование - интенсивное использование почти готовой версии ПО с целью выявления максимального числа ошибок в его работе для их последующего устранения перед окончательным выходом (релизом) продукта на рынок, к массовому потребителю. В некоторых случаях выполняется распространение версии с ограничениями (по функциональности или времени работы) для некоторой группы лиц, с тем, чтобы убедиться, что продукт содержит достаточное малое количество ошибок. Иногда бета-тестирование выполняется для того, чтобы получить обратную связь о продукте от его будущих пользователей (их называют бета-тестерами). Бета-версия не является финальной версией продукта, поэтому разработчик не гарантирует полного отсутствия ошибок, которые могут нарушить работу компьютера и привести к потере данных.

При разработке заказного ПО фазу альфа- и бета-тестирования заменяют приемосдаточные испытания. Во время этих испытаний заказчик удостоверяется, что система работает в соответствии с его потребностями (как зафиксированными в техническом задании на систему, так и не зафиксированными). Заказчик может проводить такие испытания самостоятельно, выполняя заранее подготовленные тесты системы, либо проводить их совместно с представителями исполнителя. В этом случае тестовые примеры также готовятся разработчиками, например на основе тестовых примеров, использовавшихся на этапе системного тестирования.

Завершаются приемосдаточные испытания либо подписанием акта приемки, либо выдачей заказчиком дополнительных требований к системе, которые должны быть исправлены до приемки системы. После устранения всех недостатков системы приемосдаточные испытания повторяются (возможно, по сокращенной программе). После успешного подписания акта система поступает в эксплуатацию заказчику.

· Функциональные тесты/тесты соответствия (Conformance testing/Functional testing/Correctness testing)

Эти тесты могут называться по разному, однако, их суть проста - проверка соответствия системы, предъявляемым к ней требованиям, описанным на уровне спецификации поведенческих характеристик.

Достижение и оценка надежности (Reability achievement and evaluation)

Помогая идентифицировать причины сбоев, тестирование подразумевает и повышение надежности программных систем. Случайно генерируемые сценарии тестирования могут применяться для статической оценки надежности. Обе цели - повышение и оценка надежности - могут достигаться при использовании моделей повышения надежности.

· Регрессионное тестирование (Regression testing)

Определение успешности регрессионных тестов (IEEE 610-90 “Standart Glossary of Software Engineering Terminology”) гласит: «повторное выборочное тестирование системы или компонент для проверки сделанных модификаций не должно приводить к непредусмотренным эффектам». На практике это означает, что если система успешно проходила тесты до внесения модификаций, она должна их проходить и после внесения таковых. Основная проблема регрессионного тестирования заключается в поиске компромисса между имеющимися ресурсами и необходимостью проведения таких тестов по мере внесения каждого изменения. В определенной степени, задача состоит в том, чтобы определить критерии «масштабов» изменений, с достижением которых необходимо проводить регрессионные тесты.

· Тестирование производительности (Perfomance testing)

Специализированные тесты проверки удовлетворения специфических требований, предъявляемых к параметрам производительности. Существует особый подвид таких тестов, когда делается попытка достижения количественных пределов, обусловленных характеристиками самой системы и ее операционного окружения.

· Нагрузочное тестирование (Stress testing)

Необходимо понимать отличия между рассмотренным выше тестированием производительности с целью достижения ее реальных (достижимых) возможностей производительности и выполнением программной системы с повышением нагрузки, вплоть до достижения запланированных характеристик и далее, с отслеживанием поведения на всем протяжении повышения загрузки системы.

· Сравнительное тестирование (Back-to-back testing)

Единичный набор тестов, позволяющих сравнить две версии системы.

· Восстановительные тесты (Recovery testing)

Цель - проверка возможностей рестарта системы в случае непредусмотренной катастрофы (disaster), влияющей на функционирование операционной среды, в которой выполняется система.

· Конфигурационное тестирование (Configuration testing)

В случаях, если программное обеспечение создается для использования различными пользователями (в терминах «ролей»), данный вид тестирования направлен на проверку поведения и работоспособности системы в различных конфигурациях.

· Тестирование удобства и простоты использования (Usability testing)

Цель - проверить, насколько легко конечный пользователь системы может ее освоить, включая не только функциональную составляющую - саму систему, но и ее документацию; насколько эффективно пользователь может выполнять задачи, автоматизация которых осуществляться с использованием данной системы; наконец, насколько хорошо система застрахована (с точки зрения потенциальных сбоев) от ошибок пользователя.

· Разработка, управляемая тестированием (Test-driven development)

По сути, это не столько техника тестирования, сколько стиль организации процесса разработки, жизненного цикла, когда тесты являются неотъемлемой частью требований (и соответствующих спецификаций) вместо того, чтобы рассматриваться независимой деятельностью по проверке удовлетворения требований программной системой.

 

.
Восходящее и нисходящее тестирование

 

4.1 Восходящее тестирование

 

При восходящем подходе программа собирается и тестируется снизу вверх. Только модули самого нижнего уровня («терминальные» модули; модули, не вызывающие других модулей) тестируются изолированно, автономно. После того как тестирование этих модулей завершено, вызов их должен быть так же надежен, как вызов встроенной функции языка или оператор присваивания. Затем тестируются модули, непосредственно вызывающие уже проверенные. Эти модули более высокого уровня тестируются не автономно, а вместе с уже проверенными модулями более низкого уровня. Процесс повторяется до тех пор, пока не будет достигнута вершина. Здесь завершаются и тестирование модулей, и тестирование сопряжении программы.

При восходящем тестировании для каждого модуля необходим драйвер: нужно подавать тесты в соответствии с сопряжением тестируемого модуля. Одно из возможных решении - написать для каждого модуля небольшую ведущую программу. Тестовые данные представляются как «встроенные» непосредственно в эту программу переменные и структуры данных, и она многократно вызывает тестируемый модуль, с каждым вызовом передавая ему новые тестовые данные.

Имеется и лучшее решение: воспользоваться программой тестирования модулей - это инструмент тестирования, позволяющий описывать тесты на специальном языке и избавляющий от необходимости писать драйверы.

Здесь отсутствуют проблемы, связанные с невозможностью или трудностью создания всех тестовых ситуаций, характерные для нисходящего тестирования. Драйвер как средство тестирования применяется непосредственно к тому модулю, который тестируется, где нет промежуточных модулей, которые следует принимать во внимание. Анализируя другие проблемы, возникающие при нисходящем тестировании, можно заметить, что при восходящем тестировании невозможно принять неразумное решение о совмещении тестирования с проектированием программы, поскольку нельзя начать тестирование до тех пор, пока не спроектированы модули нижнего уровня. Не существует также и трудностей с незавершенностью тестирования одного модуля при переходе к тестированию другого, потому что при' восходящем тестировании с применением нескольких версий заглушки нет сложностей с представлением тестовых данных.

Восходящее тестирование - это прекрасный способ локализации ошибок. Если ошибка обнаружена при тестировании единственного модуля, то очевидно, что она содержится именно в нем - для поиска ее источника не нужно анализировать код всей системы. А если ошибка проявляется при совместной работе двух предварительно протестированных модулей, значит, дело в их интерфейсе. Еще одним преимуществом восходящего тестирования является то, что выполняющий его программист концентрируется на очень узкой области (единственном модуле, передаче данных между парой модулей и т.п.). Благодаря этому тестирование проводится более тщательно и с большей вероятностью выявляет ошибки.

Главным недостатком восходящего тестирования является необходимое написания специального кода-оболочки, вызывающего тестируемый модуль. Если он, в свою очередь, вызывает другой модуль, для него нужно написать «заглушку». Заглушка - это имитация вызываемой функции, возвращающая те же данные, но ничего больше не делающая.

Понятно, что написание оболочек и заглушек замедляет работу, а для конечного продукта они абсолютно бесполезны. Но написанные однажды, ни элементы могут использоваться повторно при каждом изменении про-флммы. Хороший набор оболочек и заглушек - это очень эффективный инструмент тестирования.

В противоположность восходящему тестированию, стратегия целостного тестирования предполагает, что до полной интеграции системы ее отдельные модули не проходят особо тщательного тестирования.

Преимуществом такой стратегии является то, что нет необходимости в написании дополнительного кода. Поэтому многие руководители выбирают этот способ из соображений экономии времени - они считают, что лучше разработать один обширный набор тестов и с его помощью за один раз проверить всю систему. Но такое представление совершенно ошибочно, и вот почему.

Очень трудно выявить источник ошибки. Это главная проблема. Поскольку ни один из модулей не проверен как следует, в большинстве из них есть ошибки. Получается, что вопрос не столько в том, в каком модуле произошла обнаруженная ошибка, сколько в том, какая из ошибок во всех вовлеченных в процесс модулях привела к полученному результату. И когда накладываются ошибки нескольких модулей, ситуацию может быть гораздо труднее локализовать и повторить.

Кроме того, ошибка в одном из модулей может блокировать тестирование другого. Как протестировать функцию, если вызывающий ее модуль не работает? Если не написать для этой функции программу-оболочку, придется ждать отладки модуля, а это может затянуться надолго.

Трудно организовать исправление ошибок. Если программу пишут несколько программистов (а именно так и бывает в больших системах), и при этом неизвестно, в каком модуле ошибка, кто же будет ее искать и исправлять? Один программист будет указывать на другого, тот, выяснив, что его код ни при чем, снова обратится к первому, а в результате будет сильно страдать скорость разработки.

Процесс тестирования плохо автоматизирован. То, что на первый взгляд кажется преимуществом целостного тестирования - отсутствие необходимости писать оболочки и заглушки, - на самом деле оборачивается его недостатком. В процессе разработки программа ежедневно меняется, и ее приходится тестировать снова и снова. А оболочки и заглушки помогают автоматизировать этот однообразный труд.

 

4.2 Нисходящее тестирование

 

Существует и еще один принцип организации тестирования, при котором программа так же, как и при восходящем способе, тестируется не целиком, а по частям. Только направление движения меняется - сначала тестируется самый верхний уровень иерархии модулей, а от него тестировщик постепенно спускается вниз. Такая технология называется нисходящей (top-down). Обе технологии - и нисходящую и восходящую - называют также инкрементальными.

При нисходящем тестировании отпадает необходимость в написании оболочек, но заглушки остаются. По мере тестирования заглушки по очереди заменяются на реальные модули.

Мнения специалистов о том, какая из двух инкрементальных стратегий тестирования более эффективна, сильно расходятся. На практике вопрос выбора стратегии тестирования обычно решается просто: каждый модуль по возможности тестируется сразу после его написания, в результате последовательность тестирования одних частей программы может оказаться восходящей, а других - нисходящей.

Нисходящее тестирование (называемое также нисходящей разработкой не является полной противоположностью восходящему, но в первом приближении может рассматриваться как таковое, При нисходящем подходе программа собирается и тестирует

Поделиться:





Воспользуйтесь поиском по сайту:



©2015 - 2024 megalektsii.ru Все авторские права принадлежат авторам лекционных материалов. Обратная связь с нами...