учебники, программирование, основы, введение в,

 

Регрессионное тестирование: цели и задачи, условия применения, классификация тестов и методов отбора

Цели и задачи регрессионного тестирования
При корректировках программы необходимо гарантировать сохранение качества. Для этого используется регрессионное тестирование - дорогостоящая, но необходимая деятельность в рамках этапа сопровождения, направленная на перепроверку корректности измененной программы. В соответствии со стандартным определением, регрессионное тестирование - это выборочное тестирование, позволяющее убедиться, что изменения не вызвали нежелательных побочных эффектов, или что измененная система по-прежнему соответствует требованиям.
Главной задачей этапа сопровождения является реализация систематического процесса обработки изменений в коде. После каждой модификации программы необходимо удостовериться, что на функциональность программы не оказал влияния модифицированный код. Если такое влияние обнаружено, говорят о регрессионном дефекте. Для регрессионного тестирования функциональных возможностей, изменение которых не планировалось, используются ранее разработанные тесты. Одна из целей регрессионного тестирования состоит в том, чтобы, в соответствии с используемым критерием покрытия кода (например, критерием покрытия потока операторов или потока данных), гарантировать тот же уровень покрытия, что и при полном повторном тестировании программы. Для этого необходимо запускать тесты, относящиеся к измененным областям кода или функциональным возможностям.
Пусть T = {t1, t2, ..., tN} - множество из N тестов, используемое при первичной разработке программы P, а T'http://localhost:3232/img/symbols/sube.gifT - подмножество регрессионных тестов для тестирования новой версии программы P'. Информация о покрытии кода, обеспечиваемом T', позволяет указать блоки P', требующие дополнительного тестирования, для чего может потребоваться повторный запуск некоторых тестов из множества Thttp://localhost:3232/img/symbols/supe.gifT', или даже создание T'' - набора новых тестов для P' - и обновление T.
Другая цель регрессионного тестирования состоит в том, чтобы удостовериться, что программа функционирует в соответствии со своей спецификацией, и что изменения не привели к внесению новых ошибок в ранее протестированный код. Эта цель всегда может быть достигнута повторным выполнением всех тестов регрессионного набора, но более перспективно отсеивать тесты, на которых выходные данные модифицированной и старой программы не могут различаться. Результаты сравнения выборочных методов и метода повторного прогона всех тестов приведены в.


Таблица 11.1. Выборочное регрессионное тестирование и повторный прогон всех тестов.

Повторный прогон всех тестов

Выборочное регрессионное тестирование

Прост в реализации

Требует дополнительных расходов при внедрении

Дорогостоящий и неэффективный

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

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

Может приводить к пропуску ошибок

Задача отбора тестов из набора T для заданной программы P и измененной версии этой программы P' состоит в выборе подмножества T'идеальноеhttp://localhost:3232/img/symbols/sube.gifT для повторного запуска на измененной программе P', где T'идеальное = {thttp://localhost:3232/img/symbols/isin.gifT | P'(t) http://localhost:3232/img/symbols/ne.gifP(t)}. Так как выходные данные P и P' для тестов из множества Thttp://localhost:3232/img/symbols/supe.gifT'идеальное заведомо одинаковы, нет необходимости выполнять ни один из этих тестов на P'. В общем случае, в отсутствие динамической информации о выполнении P и P' не существует методики вычисления множества T'идеальное для произвольных множеств P, P' и T. Это следует из отсутствия общего решения проблемы останова, состоящей в невозможности создания в общем случае алгоритма, дающего ответ на вопрос, завершается ли когда-либо произвольная программа P для заданных значений входных данных. На практике создание T'идеальное возможно только путем выполнения на инструментированной версии P' каждого регрессионного теста, чего и хочется избежать.
Реалистичный вариант решения задачи выборочного регрессионного тестирования состоит в получении полезной информации по результатам выполнения P и объединения этой информации с данными статического анализа для получения множества T'реальное в виде аппроксимации T'идеальное. Этот подход применяется во всех известных выборочных методах регрессионного тестирования, основанных на анализе кода. Множество T'реальное должно включать все тесты из T, активирующие измененный код, и не включать никаких других тестов, то есть тест thttp://localhost:3232/img/symbols/isin.gifT входит в T'реальное тогда и только тогда, когда t задействует код P в точке, где в P' код был удален или изменен, или где был добавлен новый код.
Если некоторый тест t задействует в P тот же код, что и в P', выходные данные P и P' для t различаться не будут. Из этого следует, что если P(t)http://localhost:3232/img/symbols/ne.gifP'(t), t должен задействовать некоторый код, измененный в P' по отношению к P, то есть должно выполняться отношение thttp://localhost:3232/img/symbols/isin.gifT'реальное. С другой стороны, поскольку не каждое выполнение измененного кода отражается на выходных значениях теста, могут существовать некоторые такие thttp://localhost:3232/img/symbols/isin.gifT'реальное, что P(t) = P'(t). Таким образом, T'реальное содержит T'идеальное целиком и может использоваться в качестве его альтернативы без ущерба для качества тестируемого программного продукта.
Важной задачей регрессионного тестирования является также уменьшение стоимости и сокращение времени выполнения тестов.
Рассмотрим отбор тестов на примере. Код, покрываемый тестами, выделен цветом и штриховкой. Легко заметить, что код, покрываемый тестом 1, не изменился с предыдущей версии, следовательно, повторное выполнение теста 1 не требуется. Напротив, код, покрываемый тестами 2, 3 и 4, изменился; следовательно, требуется их повторный запуск.

http://localhost:3232/img/empty.gifhttp://localhost:3232/img/empty.gifВиды регрессионного тестирования

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

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

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

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

Прогрессивное регрессионное тестирование обычно выполняется после адаптивного или усовершенствующего сопровождения, тогда как корректирующее регрессионное тестирование выполняется во время тестирования в цикле разработки и после корректирующего сопровождения, то есть после того, как над программным обеспечением были выполнены некоторые корректирующие действия. Вообще говоря, корректирующее регрессионное тестирование должно быть более простым, чем прогрессивное регрессионное тестирование, поскольку допускает повторное использование большего количества тестов.
Подход к отбору регрессионных тестов может быть активным или консервативным. Активный подход во главу угла ставит уменьшение объема регрессионного тестирования и пренебрегает риском пропустить дефекты. Активный подход применяется для тестирования систем с высокой исходной надежностью, а также в случаях, когда эффект изменений невелик. Консервативный подход требует отбора всех тестов, которые с ненулевой вероятностью могут обнаруживать дефекты. Этот подход позволяет обнаруживать большее количество ошибок, но приводит к созданию более обширных наборов регрессионных тестов.
Управляемое регрессионное тестирование
В течение жизненного цикла программы период сопровождения длится долго. Когда измененная программа тестируется набором тестов T, мы сохраняем без изменений по отношению к тестированию исходной программы P все факторы, которые могли бы воздействовать на вывод программы. Поэтому атрибуты конфигурации, в которой программа тестировалась последний раз (например, план тестирования, тесты tj и покрываемые элементы MT(P,C,tj)), подлежат управлению конфигурацией. Практика тестирования измененной версии программы P' в тех же условиях, в которых тестировалась исходная программа P, называется управляемым регрессионным тестированием. При неуправляемом регрессионном тестировании некоторые свойства методов регрессионного тестирования могут изменяться, например, безопасный метод отбора тестов может перестать быть безопасным. В свою очередь, для обеспечения управляемости регрессионного тестирования необходимо выполнение ряда условий:

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

Предположим, что никакие операторы программы, кроме тех, чье поведение зависит от изменений, не могут неблагоприятно воздействовать на программу. Даже при таком условии существуют некоторые ситуации, требующие особого внимания, например проблема утечки памяти и ей подобные. Ситуации такого рода в разных системах программирования обрабатываются по-разному. Например, язык Java сам по себе включает систему управления памятью. Если же система не контролирует распределение памяти автоматически, мы должны считать, что все операторы работы с памятью также обладают поведением, зависящим от изменений.
Проблема языков типа C и C++, которые допускают произвольные арифметические операции над указателями, состоит в том, что указатели могут нарушать границы областей памяти, на которые они указывают. Это означает, что переменные могут обрабатываться способами, которые не поддаются анализу на уровне исходного кода. Чтобы учесть такие нарушения границ памяти, выдвигаются следующие гипотезы:

  • Гипотеза 1 (Четко определенная память). Каждый сегмент памяти, к которому обращается система программного обеспечения, соответствует некоторой символически определенной переменной.
  • Гипотеза 2 (Строго ограниченный указатель). Каждая переменная или выражение, используемое как указатель, должно ссылаться на некоторую базовую переменную и ограничиваться использованием сегмента памяти, определяемого этой переменной.

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

http://localhost:3232/img/empty.gifОбоснование корректности метода отбора тестов

Перечислим некоторые особенности реализации регрессионного тестирования.

  • Некоторые участки кода программы не получают управление при выполнении некоторых тестов.
  • Если участок кода реализует требование, но измененный фрагмент кода не получает управления при выполнении теста, то он и не может воздействовать на значения выходных данных программы при выполнении данного теста.
  • Даже если участок кода, реализующий требование, получает управление при выполнении теста, это далеко не всегда отражается на выходных данных программы при выполнении данного теста. Действительно, если изменяется первый блок программы, например, путем добавления инициализации переменной, все пути в программе также изменяются, и, как следствие, требуют повторного тестирования. Однако может так случиться, что только на небольшом подмножестве путей действительно используется эта инициализированная переменная.
  • Не каждый тест tkhttp://localhost:3232/img/symbols/isin.gifT, проверяющий код, находящийся на одном пути с измененным кодом, обязательно покрывает этот измененный код.
  • Код, находящийся на одном пути с измененным кодом, может не воздействовать на значения выходных данных измененных модулей программы.
  • Не всегда каждый оператор программы воздействует на каждый элемент ее выходных данных.

Предположим, что изменения в программе ограничиваются одним оператором. Если при выполнении какого-либо теста на исходной программе этот оператор никогда не получает управление, можно с уверенностью сказать, что он не получит управление и в ходе выполнения теста на новой программе, а результаты тестирования новой и старой программ будут совпадать. Следовательно, нет необходимости выполнять этот тест на новой программе. Указанный метод легко можно обобщить для случая нескольких изменений: если тест не задействует ни одного измененного оператора, и его входные данные не изменились, код, выполняемый им в измененной программе, будет в точности таким же, как в первоначальной версии. Такой тест не выявляет различий между двумя версиями системы; следовательно, нет необходимости прогонять его повторно. Если тест не затрагивает ни одного оператора вывода, поведение которого зависит от измененных операторов, это означает, что, несмотря на изменения в программе, все операторы, которые получают управление при выполнении этого теста, не изменят вывод системы по отношению к предыдущей версии. Таким образом, нет необходимости повторно прогонять и тесты такого рода.
Следовательно, необходимо ориентироваться на выбор только тех тестов, которые покрывают измененный код, воздействующий, в свою очередь, на вывод программы. Такой подход гарантирует, что будут выбраны только тесты, обнаруживающие изменения, и метод будет, как говорят, точным.
Классификация тестов при отборе
Создание наборов регрессионных тестов рекомендуется начинать с множества исходных тестов. При заданном критерии регрессионного тестирования все исходные тесты t (thttp://localhost:3232/img/symbols/isin.gifT) подразделяются на три подмножества:

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

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

http://localhost:3232/img/empty.gifВозможности повторного использования тестов

К изменению существующих тестов могут привести три следующих вида деятельности программистов:

  • Создание новых тестов
  • Выполнение тестов
  • Изменение кода

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

  • Уровень 1: Тест не допускает повторного использования. Требуется создание нового набора тестов (например, путем удаления или изменения этого теста).
  • Уровень 2: Повторное использование возможно только входных данных теста. Во многих случаях цель тестирования состоит в активизации некоторых покрываемых элементов программы. Если из траектории существующего теста видно, что элементы программы, подлежащие покрытию, задействуются до измененных команд, входные данные теста могут быть использованы повторно для покрытия этих элементов. В результате изменений в программе и/или техническом задании новая траектория и выходные данные теста могут отличаться от результатов предыдущего выполнения. Таким образом, тесты первого уровня должны быть запущены повторно для получения новых выходных данных и траекторий.
  • Уровень 3: Возможно повторное использование как входных, так и выходных данных теста. Очевидно, что на этом уровне обычно располагаются функциональные тесты. Если модуль подвергся только изменению кода с сохранением функциональности, возможно повторное использование существующих функциональных тестов для проверки правильности реализации. Поскольку траектория может измениться, а выходные данные - подвергнуться воздействию со стороны изменений кода, такие тесты должны быть запущены повторно, но ожидается получение идентичных результатов.
  • Уровень 4: Наивысший уровень повторного использования теста, предусматривающий повторное использование входных данных, выходных данных и траектории теста. В этом случае на траектории теста не изменяется ни один оператор. Следовательно, в повторном запуске этих тестов необходимости нет, так как выходные данные и траектория останутся неизменными.

Пример регрессионного тестирования функции решения квадратного уравнения.

Код этой функции приведен на. Входными параметрами являются коэффициенты квадратного уравнения A, B и C, а также флаг Print, ненулевое значение которого указывает, что полученное решение необходимо вывести на экран. К выходным параметрам относятся X1 и X2, предназначенные для хранения корней уравнения, и возвращаемое значение функции - дискриминант уравнения. В исходном виде функция содержит дефект, в результате чего уравнения с отрицательным дискриминантом порождают ошибку времени выполнения. В новой версии функции дефект должен быть исправлен; кроме того, необходимо реализовать запрос пользователя на изменение формата вывода решения. Код новой версии функции Equation приводится на.
Существующие тесты для функции Equation приведены в. Входные данные тестов представляют собой совокупность значений Print, A, B и C, подаваемых на вход функции. Выходными данными для теста являются значения X1 и X2, возвращаемое значение функции, а также строка, выводимая на экран; вприведены ожидаемые значения выходных данных. Кроме того, для каждого теста вычисляется траектория его прохождения по коду.

double Equation(int Print, float A, float B, float C,
                float& X1, float& X2)
{
 float D = B * B - 4.0 * A * C;
 if (D >= 0)
 {
  X1 = (-B + sqrt(D)) / 2.0 / A;
  X2 = (-B - sqrt(D)) / 2.0 / A;
 }
 else
 {
  X1 = -B / 2.0 / A;
  X2 = sqrt(D);
 }
 if (Print)
  printf("Solution: %f, %f\n", X1, X2);
 return D;
}

Пример 11.1. Функция Equation - исходная версия.

double Equation(int Print, float A, float B, float C,
                float& X1, float& X2)
{
 float D = B * B - 4.0 * A * C;
 if (D >= 0)
 {
  X1 = (-B + sqrt(D)) / 2.0 / A;
  X2 = (-B - sqrt(D)) / 2.0 / A;
 }
 else
 {
  X1 = -B / 2.0 / A;
  X2 = sqrt(D);
 }
 if (Print)
  printf("Solution: %f, %f\n", X1, X2);
 return D;
}

Пример 11.1.1. Функция Equation - исходная версия.

double Equation(int Print, float A, float B, 
       float C, float& X1, float& X2)
{
 float D = B * B - 4.0 * A * C;
 
 if (D >= 0)
 {
  X1 = (-B + sqrt(D)) / 2.0 / A;
  X2 = (-B - sqrt(D)) / 2.0 / A;
 }
 else
 {
  X1 = -B / 2.0 / A;
  X2 = sqrt(-D);
 }
 if (Print)
 {
  if (D >= 0)
   printf("Solution: X1 = %f, X2 = %f\n", X1, X2);
  else
   printf("Solution: X1 = %f+%fi, X2 = %f-%fi\n", 
           X1, X2, X1, X2);
 }
 
 return D;
}

Пример 11.2. Функция Equation - измененная версия.

double Equation(int Print, float A, float B,
       float C, float& X1, float& X2)
{
 float D = B * B - 4.0 * A * C;
 
 if (D >= 0)
 {
  X1 = (-B + sqrt(D)) / 2.0 / A;
  X2 = (-B - sqrt(D)) / 2.0 / A;
 }
 else
 {
  X1 = -B / 2.0 / A;
  X2 = sqrt(-D);
 }
 if (Print)
 {
  if (D >= 0)
   printf("Solution: X1 = %f, X2 = %f\n", X1, X2);
  else
   printf("Solution: X1 = %f+%fi, X2 = %f-%fi\n", 
           X1, X2, X1, X2);
 }
 
 return D;
}

Пример 11.2.1. Функция Equation - измененная версия.
При изменении функции Equation отменяется формат выводимых на экран данных, так что тесты 1 и 2, проверяющие вывод на экран, могут быть повторно использованы только на уровне 2. Тесты 3, 4 и 5 могут быть использованы на уровне 3 или 4 в зависимости от результатов анализа их траектории.

http://localhost:3232/img/empty.gifhttp://localhost:3232/img/empty.gifКлассификация выборочных методов

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

             

Таблица 11.2. Входные и выходные данные тестов

Тест

Входные данные

Ожидаемые выходные данные

A

B

C

Print

X1

X2

Возвращаемое значение

Выводимая строка

1

1

1

-6

1

2

-3

25

Solution: X1 = 2, X2 = -3

2

2

-3

5

1

0.75

5.567764

-31

Solution: X1 = 0.75+5.567764i, X2 = 0.75-5.567764I

3

1

2

0

0

0

-2

4

4

1

2

1

0

-1

-1

0

5

1

2

2

0

-1

2

-4

Полнота отражает меру отбора тестов из T, на которых результат выполнения измененной программы отличен от результата выполнения исходной программы, вследствие чего могут быть обнаружены ошибки в P'. Метод, полный на 100%, называется безопасным.
Точность - мера способности метода избегать выбора тестов из T, на которых результат выполнения измененной программы не будет отличаться от результата ее первоначальной версии, то есть тестов, неспособных обнаруживать ошибки в P'. Предположим, что набор T содержит r регрессионных тестов. Из них для n тестов (nhttp://localhost:3232/img/symbols/le.gifr) поведение и результаты выполнения старой программы P отличаются от поведения и результатов выполнения новой программы P'. Набор тестов T'http://localhost:3232/img/symbols/sube.gifT содержит m (mhttp://localhost:3232/img/symbols/ne.gif0) тестов, полученных с использованием метода отбора регрессионных тестов M. Из этих m тестов для l тестов поведение P' и P различается. Точность T' относительно P, P', T и M, выраженная в процентах, определяется выражением 100 * (l / m), тогда как соответствующий процент выбранных тестов определяется выражением 100 * (l / n), если n http://localhost:3232/img/symbols/ne.gif0 или равен 100%, если n = 0.
Исходя из приведенного определения, точность множества тестов - это отношение числа тестов данного множества, на которых результаты выполнения новой и старой программ различаются, к общему числу тестов множества. Точность является важным атрибутом метода регрессионного тестирования. Неточный метод имеет тенденцию отбирать тесты, которые не должны были быть выбраны. Чем менее точен метод, тем ближе объем выбранного набора тестов к объему исходного набора тестов.
Эффективность - оценка вычислительной стоимости стратегии выборочного регрессионного тестирования, то есть стоимости реализации ее требований по времени и памяти, а также возможности автоматизации. Относительной эффективностью называется эффективность метода тестирования при условии наличия не более одной ошибки в тестируемой программе. Абсолютной эффективностью называется эффективность метода в реальных условиях, когда оценка количества ошибок в программе не ограничена.
Универсальность отражает меру способности метода к применению в достаточно широком диапазоне ситуаций, встречающихся на практике.
Для программы P, ее измененной версии P' и набора тестов T для P требуется, чтобы методика выборочного повторного тестирования удовлетворяла следующим критериям оценки:

  • Критерий 1 - Безопасность. Методика выборочного повторного тестирования должна быть безопасной, то есть должна выбирать все тесты из T, которые потенциально могут обнаруживать ошибки (все тесты, чье поведение на P' и P может быть различным). Безопасная методика должна рассматривать последствия добавления, удаления и изменения кода. При добавлении нового кода в P в T могут уже содержаться тесты, покрывающие этот новый код. Такие тесты необходимо обнаруживать и учитывать при отборе.
  • Критерий 2 - Точность. Стратегия повторного прогона всех тестов является безопасной, но неточной. В дополнение к выбору всех тестов, потенциально способных обнаруживать ошибки, она также выбирает тесты, которые ни в коем случае не могут демонстрировать измененное поведение. В идеале, методика выборочного повторного тестирования должна быть точной, то есть должна выбирать только тесты с изменившимся поведением. Однако для произвольно взятого теста, не запуская его, невозможно определить, изменится ли его поведение. Следовательно, в лучшем случае мы можем рассчитывать лишь на некоторое увеличение точности.

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

  • Критерий 3 - Эффективность. Методика выборочного повторного тестирования должна быть эффективной, то есть должна допускать автоматизацию и выполняться достаточно быстро для практического применения в условиях ограниченного времени регрессионного тестирования. Методика должна также предусматривать хранение информации о ходе исполнения тестов в минимально возможном объеме.
  • Критерий 4 - Универсальность. Методика выборочного повторного тестирования должна быть универсальной, то есть применимой ко всем языкам и языковым конструкциям, эффективной для реальных программ и способной к обработке сколь угодно сложных изменений кода.

В общем случае существует некоторый компромисс между безопасностью, точностью и эффективностью. При отборе тестов анализ необходимо провести за время, меньшее, чем требуется для выполнения и проверки результатов тестов из T, не вошедших в T'. С учетом этого ограничения решением задачи регрессионного тестирования будет безопасный метод с хорошим балансом дешевизны и высокой точности.
http://localhost:3232/img/empty.gif

 
На главную | Содержание | < Назад....Вперёд >
С вопросами и предложениями можно обращаться по nicivas@bk.ru. 2013 г.Яндекс.Метрика