Тема: Тестирование программного обеспечения

  • Вид работы:
    Курсовая работа (т)
  • Предмет:
    Информационное обеспечение, программирование
  • Язык:
    Русский
  • Формат файла:
    MS Word
  • Размер файла:
    48,72 Кб
Тестирование программного обеспечения
Тестирование программного обеспечения
Вы можете узнать стоимость помощи в написании студенческой работы.
Помощь в написании работы, которую точно примут!

Министерство образования и науки Российской Федерации

Федеральное государственное бюджетное образовательное

учреждение высшего профессионального образования

«ТВЕРСКОЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ»

Математический факультет

Кафедра компьютерной безопасности и математических методов управления







КУРСОВАЯ РАБОТА

по дисциплине Методы программирования

на тему

Тестирование программного обеспечения

Выполнила:

студентка 35 группы математического факультета

специальность

Компьютерная безопасность

Кушнер Кристина Александровна

Проверила:

доцент кафедры КБиММУ

Цирулева Валентина Михайловна

Тверь, 2013 г.

Тестирование ПО. Неразрешимость проблемы тестирования. Виды и уровни тестирования. Стратегии восходящего и нисходящего тестирования. Методы "белого" и "черного" ящика. Автоматизированное и ручное тестирование. Разработка через тестирование (TDD). Непрерывная интеграция. Покрытие кода тестами.

Содержание

1. Вступление.

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

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

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

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

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

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

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

.2 Уровни тестирования.

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

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

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

.3 Технология восходящего и нисходящего тестирования.

. Методы "белого" и "черного" ящика.

.1 Метод «белого ящика».

.2 Метод «черного ящика».

.3 Метод «серого ящика».

. Автоматизированное и ручное тестирование.

.1 Автоматизированное тестирование.

.2 Ручное тестирование.

. Разработка через тестирование (TDD).

.1 Основные понятия TDD.

.2 Требования.

7.3 Цикл разработки через тестирование.

.4 Запуск всех тестов: убедиться, что новые тесты не проходят.

.5 Запуск всех тестов: убедиться, что все тесты проходят.

.6 Рефакторинг

7.7 Стиль разработки.

.8 Преимущества.

.9 Слабые места.

. Непрерывная интеграция.

.1 Понятие непрерывной интеграции.

8.2 Требования к проекту.

8.3 Организация. 6

8.4 Сборка по расписанию.

8.5 Преимущества.

.6 Недостатки.

8.7 Средства непрерывной интеграции.

9. Покрытие кода тестами.

.1 Покрытие кода.

.2 Практическое применение.

Литература.

Приложение 1.

Приложение 2.

1.Введение

.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) предполагает проверку соответствия ПО требованиям к графическому интерфейсу пользователя. Различают следующие виды тестирования графического интерфейса пользователя:

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

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

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

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

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

·Тестирование авторизации пользователей - выявляет дефекты, связанные с авторизацией отдельных пользователей и г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Нисходящее тестирование

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

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

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

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

Интересен и второй вопрос: в какой форме готовятся тестовые данные и как они передаются программе? Если бы головной модуль содержал все нужные операции ввода и вывода, ответ был бы прост:

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

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

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

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

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

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

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

4.3Технология восходящего и нисходящего тестирования

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

·от периферии к центру (восходящее тестирование) или, наоборот,

·от центра к периферии (нисходящее тестирование).

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

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

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

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

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

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

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

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

Проведем сравнение нисходящего и восходящего тестирования [Таблица 1].

Значительное повышение корректности и надежности программ достигается применением двойного или N-кратного программирования (Duplication Check - двойной просчет, двойная проверка).

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

В заключение заметим, что если исполнение теста приносит результаты, не соответствующие предполагаемым, то это означает, что:

·либо модуль имеет ошибку;

·либо неверны предполагаемые результаты (ошибки в тесте).

Для устранения такого рода недоразумений нужно тщательно проверять набор тестов ("тестировать" тесты).

.Тестирование методами «белого», «черного» и «серого ящика»

5.1Тестирование методом «белого ящика»

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

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

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

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

·Дают гарантию того, что все независимые пути в модуле проверены по крайней мере один раз.

·Проверяют все логические решения на предмет того, истины они или ложны.

·Выполняют все циклы внутри операционных границ и с использованием граничных значений.

·Исследуют структуры внутренних данных с целыо проверки их достоверности.

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

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

Методы тестирования на основе стратегии белого ящика:

·Ввод неверных значений. При вводе неверных значений тестировщик заставляет коды возврата показывать ошибки и смотрит на реакцию кода. Это хороший способ моделирования определенных событий, например переполнения диска, нехватки памяти и т.д. Популярным методом является замена alloc() функцией, которая возвращает значение NULL в 10% случаев с целью выяснения, сколько сбоев будет в результате. Такой подход еще называют тестированием ошибочных входных данных. При таком тестировании проверяется обработка как верных, так и неверных входных данных. Тестировщики могут выбрать значения, которые проверяют диапазон входных/выходных параметров, а также значения, выходящие за границу диапазона.

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

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

·Утечка памяти. При тестировании утечки памяти приложение исследуется с целью обнаружения ситуаций, при которых приложение не освобождает выделенную память, в результате чего снижается производительность или возникает тупиковая ситуация. Данная технология применяется как для тестирования версии приложения, так и для тестирования готового программного продукта. Возможно применение инструментов тестирования. Они могут следить за использованием памяти приложения в течение нескольких часов или даже дней, чтобы проверить, будет ли расти объем используемой памяти. С их помощью можно также выявить те операторы программы, которые не освобождают выделенную память.

·Комплексное тестирование. Целью комплексного тестирования является проверка того, что каждый модуль программного продукта корректно согласуется с остальными модулями продукта. При комплексном тестировании может использоваться технология обработки сверху вниз и снизу вверх, при которой каждый модуль, являющийся листом в дереве системы, интегрируется со следующим модулем более низкого или более высокого уровня, пока не будет создано дерево программного продукта. Эта технология тестирования направлена на проверку не только тех параметров, которые передаются между двумя компонентами, но и на проверку глобальных параметров и, в случае объектно-ориентированного приложения, всех классов верхнего уровня.

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

·Исследование покрытия. При выборе инструмента для исследования покрытия важно, чтобы группа тестирования проанализировала тип покрытия, необходимый для приложения. Исследование покрытия можно провести с помощью различных технологий. Метод покрытия операторов часто называют С1, что также означает покрытие узлов. Эти измерения показывают, был ли проверен каждый исполняемый оператор. Данный метод тестирования обычно использует программу протоколирования (profiler) производительности.

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

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

5.2Тестирование методом «черного ящика»

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

Тестирование на основе стратегии черного ящика возможно лишь при наличии установленных открытых интерфейсов, таких как интерфейс пользователя или программный интерфейс приложения (API). Если тестирование на основе стратегии белого ящика исследует внутреннюю работу программы, то методы тестирования черного ящика сравнивают поведение приложения с соответствующими требованиями. Кроме того, эти методы обычно направлены на выявление трех основных видов ошибок: функциональности, поддерживаемой программным продуктом; производимых вычислений; допустимого диапазона или области действия значений данных, которые могут быть обработаны программным продуктом. На этом уровне тестировщики не исследуют внутреннюю работу компонентов программного продукта, тем не менее они проверяются неявно. Группа тестирования изучает входные и выходные данные программного продукта. В этом ракурсе тестирование с помощью методов черного ящика рассматривается как синоним тестирования на уровне системы, хотя методы черного ящика могут также применяться во время модульного или компонентного тестирования.

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

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

vНеверная или пропущенная функциональность

vОшибки интерфейса

vПроблемы удобства использования

vМетоды тестирования на основе Автоматизированные инструменты

vОшибки в структурах данных или ошибки доступа к внешним базам данных

vПроблемы снижения производительности и другие ошибки производительности

vОшибки загрузки

vОшибки многопользовательского доступа

vОшибки инициализации и завершения

vПроблемы сохранения резервных копий и способности к восстановлению работы

vПроблемы безопасности

vМетоды тестирования на основе стратегии черного ящика

üЭквивалентное разбиение. Исчерпывающее тестирование входных данных, как правило, неосуществимо. Поэтому следует проводить тестирование с использованием подмножества входных данных.

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

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

üДиаграммы причинно-следственных связей. Составление диаграмм причинно-следственных связей - это метод, дающий четкое представление о логических условиях и соответствующих действиях. Метод предполагает четыре этапа. Первый этап заключается в составлении перечня причин (условий ввода) и следствий (действий) для модуля и в присвоении идентификатора каждому модулю. На втором этапе разрабатывается диаграмма причинно-следственных связей. На третьем этапе диаграмма преобразуется в таблицу решений. Четвертый этап включает в себя установление причин и следствий в процессе чтения спецификации функций. Каждой причине и следствию присваивается собственный идентификатор. Причины перечисляются в столбике с левой стороны листа бумаги, а следствия - с правой. Затем причины и следствия соединяются линиями так, чтобы были отражены имеющиеся между ними соответствия. На диаграмме проставляются булевы выражения, которые объединяют две или более причин, связанных со следствием. Далее правила таблицы решений преобразуются в тестовые процедуры.

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

üФункциональное тестирование. Функциональное тестирование проверяет системное приложение в отношении функциональных требований с целью обнаружения несоответствия требованиям конечного пользователя. Для большинства программ тестирования программного продукта данный метод тестирования является главным. Его основная задача - оценка того, работает ли приложение в соответствии с предъявляемыми требованиями.

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

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

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

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

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

.3Тестирование методом «серого ящика»

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

.Автоматизированное и ручное тестирование

6.1Автоматизированное тестирование

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

Традиционный и наиболее популярный среди разработчиков способ состоит в организации автоматизации тестирования на уровне кода. Данный подход будет подробно рассмотрен при описании модульного тестирования. Автоматизированное тестирование на уровне кода часто критикуют за невозможность тестирования пользовательского интерфейса программы. Однако сторонники TDD показали, что при правильном использовании паттернов семейства MVC (Model-View-Controller) возможно организовать программную имитацию действий пользователя без использования GUI (Graphical User Interface). Этот подход позволяет организовать тестирование обработчиков действий пользователя, оставляя не покрытой тестами лишь часть, относящуюся к непосредственному отображению данных.

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

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

.Утилиты записи и воспроизведения (capture/playback tools) записывают действия во время ручного тестирования. В дальнейшем они позволяют воспроизвести ранее записанные действия без участия человека, значительно увеличивая продуктивность и устраняя повторение однообразных действий. Основным недостатком инструментальных средств данного поколения является то, что любое изменение расположения визуальных элементов программы приводит к необходимости повторной записи ручных тестов.

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

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

.При использовании keyword-based testing создается специализированный словарь ключевых слов, описывающих системные события (например, «Logon User»). С каждым ключевым словом связаны необходимые параметры (например: «UserID», «Password») и ожидаемые результаты. Для каждого ключевого слова должно быть задано описание. Данный подход позволяет писать функциональные тесты практически на естественном языке, не требуя от тестировщика навыков программирования.

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

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

6.2Ручное тестирование

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

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

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

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

. Составление тестов с описанием выполнения и ожидаемым результатом;

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

. Передача результатов тестов разработчикам в подробном докладе с описанием всех выявленных проблем для обсуждения и исправления дефектов.

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

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

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

.Разработка через тестирование

.1 Основные понятия TDD.

Разработка через тестирование (англ. test-driven development) - техника программирования, при которой модульные тесты для программы или её фрагмента пишутся до самой программы (англ. test-first development) и, по существу, управляют её разработкой. Является одной из основных практик экстремального программирования.

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

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

Методика разработки через тестирование(Test-Driven Development, TDD) позволяет получить ответы на вопросы об организации автоматических тестов и выработке определенных навыков тестирования.

«Чистый код, который работает» - в этой короткой, но содержательной фразе, кроется весь смысл методики разработки приложений через тестирование. Чистый код, который работает, - это цель, к которой стоит стремиться, и этому есть причины:

·Это предсказуемый способ разработки программ. Разработчик знает, когда работу следует считать законченной, и можете не беспокоиться о длинной череде ошибок.

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

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

·Разработчику приятнее писать такой код.

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

·Пишем новый код только тогда, когда автоматический код не сработал.

·Удаляем дублирование.

Два столь простых правила на самом деле генерируют сложное индивидуальное и групповое поведение со множеством технических последствий:

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

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

·Наша среда разработки должна быстро реагировать на небольшие модификации кода.

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

Два упомянутых правила TDD определяют порядок этапов программирования:

1.Красный - напишите небольшой тест, который не работает, а возможно, даже не компилируется.

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

.Рефакторинг - удалите из написанного вами кода любое дублирование.

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

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

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

В 1999 году при своём появлении разработка через тестирование была тесно связана с концепцией «сначала тест» (англ. <#"justify">7.2Требования

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

Тест содержит проверки условий, которые могут либо выполняться, либо нет. Когда они выполняются, говорят, что тест пройден. Прохождение теста подтверждает поведение, предполагаемое программистом. Разработчики часто пользуются библиотеками для тестирования (англ. <#"justify">7.3Цикл разработки через тестирование

Графическое представление цикла разработки, в виде блок-схемы (Приложение 1).

Приведенная последовательность действий основана на книге Кента Бека «Разработка через тестирование: на примере».

.4Запуск всех тестов: убедиться, что новые тесты не проходят

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

.5Запуск всех тестов: убедиться, что все тесты проходят


.6Рефакторинг

Когда достигнута требуемая функциональность, на этом этапе код может быть почищен. Рефакторинг <#"justify">7.7Стиль разработки

Разработка через тестирование тесно связана с такими принципами как

«делай проще, дурачок» (англ. <#"justify">7.8Преимущества

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

Разработка через тестирование предлагает больше, чем просто проверку корректности, она также влияет на дизайн программы. Изначально сфокусировавшись на тестах, проще представить, какая функциональность необходима пользователю. Таким образом, разработчик продумывает детали интерфейса до реализации. Тесты заставляют делать свой код более приспособленным для тестирования. Например, отказываться от глобальных переменных, одиночек (singletons), делать классы менее связанными и легкими для использования. Сильно связанный код или код, который требует сложной инициализации, будет значительно труднее протестировать. Модульное тестирование способствует формированию четких и небольших интерфейсов. Каждый класс будет выполнять определенную роль, как правило небольшую. Как следствие, зависимости между классами будут снижаться, а зацепление повышаться. Контрактное программирование <#"justify">7.9Слабые места

Главным недостатком TDD является то, что к нему сложно привыкнуть, из-за ряда причин, включая увеличение за счёт него времени перед написанием основного кода программ и увеличение объёма кода в целом.

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

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

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

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

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

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

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

.Непрерывная интеграция

.1 Понятие непрерывной интеграции

Непрерывная интеграция (англ. <#"justify">8.2Требования к проекту

·Исходный код и всё, что необходимо для сборки и тестирования проекта, хранится в репозитории системы управления версиями <#"justify">8.3Организация

На выделенном сервере организуется служба, в задачи которой входят:

·получение исходного кода из репозитория;

·сборка проекта;

·выполнение тестов;

·развёртывание готового проекта;

·отправка отчетов.

Локальная сборка может осуществляться:

·по внешнему запросу,

·по расписанию,

·по факту обновления репозитория <#"justify">.4Сборка по расписанию

В случае сборки по расписанию (англ. <#"justify">8.5Преимущества

·проблемы интеграции выявляются и исправляются быстро, что оказывается дешевле;

·немедленный прогон модульных тестов для свежих изменений;

·постоянное наличие текущей стабильной версии вместе с продуктами сборок - для тестирования, демонстрации, и т. п.

·немедленный эффект от неполного или неработающего кода приучает разработчиков к работе в итеративном режиме с более коротким циклом.

.6Недостатки

·затраты на поддержку работы непрерывной интеграции;

·потенциальная необходимость в выделенном сервере под нужды непрерывной интеграции;

·немедленный эффект от неполного или неработающего кода отучает разработчиков от выполнения периодических резервных включений кода в репозиторий.

·в случае использования системы управления версиями исходного кода с поддержкой ветвления, эта проблема может решаться созданием отдельной «ветки» (англ. branch) проекта для внесения крупных изменений (код, разработка которого до работоспособного варианта займет несколько дней, но желательно более частое резервное копирование в репозиторий). По окончании разработки и индивидуального тестирования такой ветки, она может быть объединена (англ. merge) с основным кодом или «стволом» (англ. trunk) проекта.

.7Средства непрерывной интеграции

·Bamboo <#"justify">9.Покрытие кода тестами

.1 Покрытие кода

Определения для общего понимания темы:

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

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

Покрытие требований (Requirements Coverage) - оценка покрытия тестами функциональных и не функциональных требований к продукту путем построения матриц трассировки (traceability matrix);

·Покрытие кода (Code Coverage) - оценка покрытия исполняемого кода тестами, путем отслеживания непроверенных в процессе тестирования частей программного обеспечения.

Покрытие кода является важной метрикой для обеспечения качества тестируемого приложения, особенно если речь о проектах со сложной логикой и большим объемом кода. Анализ покрытия кода выполняется с помощью специального инструментария, который позволяет проследить в какие строки, ветви и т.д. кода, были вхождения во время работы автотестов. Наиболее известные инструменты для проведения измерения покрытия кода: AQTime, Bounds Checker, Bullseye Coverage, Coverage Meter, Clover, NCover, IBM Rational PurifyPlus, Intel Compiler, Intel Code Coverage Tool Prototype, JetBrains. С помощью анализа покрытия кода можно оценить плотность покрытия авто-тестами исполняемого кода тестируемого приложения (можно ответить на вопрос какой объем тестирования мы (наши автотесты) выполняем?). При детальном анализе результатов покрытия кода автотестами можно оценить покрытие отдельных компонентов системы (т.е. можно ответить на вопросы: что и в каком объеме мы тестируем?, в каких местах нужно оптимизировать покрытие?, какие места системы не проверяются тестами? и т.д.). Таким образом, зная данную метрику, станет ясно для каких тестовых случаев нужно создать новые тесты, или убрать дублирующие тесты. Данные мероприятия помогут увеличить значение метрики Code Coverage, что в свою очередь должно повысить качество кода и качество тестируемого приложения в целом. Естественно, чем выше показатель данной метрики - тем лучше, однако уже хорошо если у вас покрыты тестами наиболее сложные и важные фрагменты кода.

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

Техника покрытия кода была одной из первых методик, изобретённых для систематического тестирования программного обеспечения <#"justify">·Покрытие операторов - каждая ли строка исходного кода была выполнена и протестирована?

·Покрытие условий - каждая ли точка решения (вычисления истинно ли или ложно выражение) была выполнена и протестирована?

·Покрытие путей - все ли возможные пути через заданную часть кода были выполнены и протестированы?

·Покрытие функций - каждая ли функция программы была выполнена?

·Покрытие вход/выход - все ли вызовы функций и возвраты из них были выполнены?

·Покрытие комбинаций - проверка всех возможных комбинаций результатов условий.

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

.2 Практическое применение

Обычно исходный код снабжается тестами, которые регулярно выполняются. Полученный отчёт анализируется с целью выявить невыполнявшиеся области кода, набор тестов обновляется, пишутся тесты для непокрытых областей. Цель состоит в том, чтобы получить набор тестов для регрессионного тестирования <#"justify">Литература

1) Анашкина Н.В., Петухова Н.Н., Смольянинов В.Ю. Технологии и методы программирования.

) Кнут Д. Искусство программирования для ЭВМ

) Соммервил И., Инженерия программного обеспечения. 6-е изд.

) Орлов С.А., Технологии разработки программного обеспечения.

) Брауде Эрик Дж., Технология разработки программного обеспечения.

) Жоголев Е.А., Технология программирования.

) Мейер Б., Бодуэн К. Методы программирования.

8) <#"justify">Приложение 1

Тест

прошел






Тест Один из тестов

не прошел не прошел



Все тесты







Приложение 2

Сравнение восходящего и нисходящего тестированияПреимуществаНедостаткиНисходящее тестирование1. Имеет преимущества, если ошибки, главным образом, в верхней части программы.1. Необходимо разрабатывать модули-заглушки, которые часто оказываются сложнее, чем кажется вначале.2. Раннее формирование структуры программы позволяет провести ее демонстрацию пользователю и служит моральным стимулом.2. Может оказаться трудным или невозможным создать тестовые условия.3. Сложнее оценка результатов тестирования.4. Стимулируется незавершение тестирования некоторых модулей.Восходящее тестирование1. Имеет преимущества, если ошибки, главным образом, в модуле нижнего уровня.1. Программа как единое целое не существует до тех пор, пока не добавлен последний модуль.2. Легче создавать тестовые примеры.3. Проще оценка результатов.

Похожие работы

 

Не нашел материала для курсовой или диплома?
Пишем качественные работы
Без плагиата!