Мутационное тестирование
Мутационное тестирование (или анализ мутаций , или программная мутация ) используется для разработки новых тестов программного обеспечения и оценки качества существующих тестов программного обеспечения. Мутационное тестирование включает в себя небольшое изменение программы. [1] Каждая мутировавшая версия называется мутантом , и тесты обнаруживают и отвергают мутантов, заставляя поведение исходной версии отличаться от поведения мутанта. Это называется убийством мутанта. Наборы тестов измеряются процентом убитых ими мутантов. Новые тесты могут быть разработаны для уничтожения дополнительных мутантов. Мутанты основаны на четко определенных операторах мутации , которые либо имитируют типичные ошибки программирования (например, использование неправильного оператора или имени переменной), либо заставляют создавать ценные тесты (например, деление каждого выражения на ноль). Цель состоит в том, чтобы помочь тестировщику разработать эффективные тесты или обнаружить слабые места в тестовых данных, используемых для программы, или в разделах кода, к которым редко или никогда не обращаются во время выполнения . Мутационное тестирование — это форма тестирования «белого ящика» . [2] [3]
Введение
[ редактировать ]Большая часть этой статьи посвящена «мутации программы», при которой программа модифицируется. Более общее определение анализа мутаций заключается в использовании четко определенных правил, определенных в синтаксических структурах, для внесения систематических изменений в программные артефакты. [4] Мутационный анализ применялся и к другим проблемам, но обычно его применяют к тестированию. Таким образом, мутационное тестирование определяется как использование мутационного анализа для разработки новых тестов программного обеспечения или оценки существующих тестов программного обеспечения. [4] Таким образом, анализ и тестирование мутаций можно применять к моделям проектирования, спецификациям, базам данных, тестам, XML и другим типам программных артефактов, хотя мутация программ является наиболее распространенной. [5]
Обзор
[ редактировать ]Тесты могут создаваться для проверки правильности реализации данной программной системы, но создание тестов по-прежнему ставит вопрос, являются ли тесты корректными и в достаточной ли степени покрывают требования, породившие реализацию. [6] (Эта технологическая проблема сама по себе является примером более глубокой философской проблемы, называемой « Quis custodiet ipsos custodes? » [«Кто будет охранять охрану?»].) Идея тестирования мутаций заключается в том, что если вводится мутант, это обычно вызывает ошибка в функционале программы, которую должны найти тесты. Таким образом тесты проверяются. Если мутант не обнаруживается набором тестов, это обычно означает, что набор тестов не может обнаружить недостатки, представленные мутантом, но это также может указывать на то, что мутация не вызывает ошибок, то есть мутация является действительным изменением. это не влияет на функциональность. Один (распространенный) способ, которым мутант может быть действительным, заключается в том, что измененный код является «мертвым кодом», который никогда не выполняется.
Чтобы мутационное тестирование функционировало в большом масштабе, обычно вводится большое количество мутантов, что приводит к компиляции и выполнению чрезвычайно большого количества копий программы. Эта проблема, связанная с расходами на мутационное тестирование, снизила его практическое использование как метода тестирования программного обеспечения. Однако более широкое использование объектно-ориентированных языков программирования и сред модульного тестирования привело к созданию инструментов мутационного тестирования, которые тестируют отдельные части приложения.
Цели
[ редактировать ]Целей мутационного тестирования несколько:
- выявлять слабо проверенные куски кода (те, по которым мутантов не убивают) [1]
- выявить слабые тесты (те, которые никогда не убивают мутантов) [7]
- вычислить показатель мутации, [4] показатель мутации представляет собой количество убитых мутантов / общее количество мутантов.
- узнать о распространении ошибок и заражении состояний в программе
История
[ редактировать ]Мутационное тестирование было первоначально предложено Ричардом Липтоном, будучи студентом, в 1971 году. [8] и впервые разработан и опубликован ДеМилло, Липтоном и Сэйвордом. [1] Первую реализацию инструмента тестирования мутаций осуществил Тимоти Бадд в рамках своей докторской работы (под названием « Анализ мутаций ») в 1980 году в Йельском университете . [9]
В последнее время, с появлением огромных вычислительных мощностей, в компьютерном сообществе возродился анализ мутаций, и была проделана работа по определению методов применения мутационного тестирования к объектно-ориентированным языкам программирования и непроцедурным языкам, таким как XML . SMV и конечные автоматы .
В 2004 году компания Certess Inc. (ныне часть Synopsys ) распространила многие принципы на область проверки оборудования. В то время как анализ мутаций предполагает обнаружить только разницу в полученных выходных данных, Certess расширяет его, проверяя, что программа проверки на тестовом стенде действительно обнаружит разницу. Это расширение означает, что оцениваются все три этапа проверки, а именно: активация, распространение и обнаружение. Они назвали это функциональной квалификацией.
Фаззинг можно рассматривать как частный случай мутационного тестирования. При фаззинге сообщения или данные, которыми обмениваются внутри коммуникационных интерфейсов (как внутри, так и между экземплярами программного обеспечения), изменяются, чтобы выявить сбои или различия в обработке данных. Кодомикон [10] (2001) и Mu Dynamics (2005) развили концепции фаззинга до платформы тестирования мутаций с полным сохранением состояния, оснащенной мониторами для тщательной проверки реализации протоколов.
Обзор мутационного тестирования
[ редактировать ]Тестирование мутаций основано на двух гипотезах. Первая — это гипотеза компетентного программиста . Эта гипотеза утверждает, что компетентные программисты пишут программы, близкие к правильным. [1] «Закрыть» должно основываться на поведении, а не на синтаксисе. Вторая гипотеза называется эффектом связи . Эффект связи утверждает, что простые неисправности могут каскадно или объединяться , образуя другие возникающие неисправности. [11] [12]
Тонкие и важные дефекты также выявляются мутантами более высокого порядка, что еще раз подтверждает эффект сцепления. [13] [14] [7] [15] [16] Мутанты более высокого порядка возникают за счет создания мутантов с более чем одной мутацией.
Тестирование мутаций выполняется путем выбора набора операторов мутации и последующего применения их к исходной программе по одному для каждого применимого фрагмента исходного кода. Результат применения к программе одного оператора мутации называется мутантом . Если набор тестов способен обнаружить изменение (т. е. один из тестов не пройден), то мутант считается убитым .
Например, рассмотрим следующий фрагмент кода C++:
if (a && b) {
c = 1;
} else {
c = 0;
}
Оператор мутации условия заменит &&
с ||
и произвести следующий мутант:
if (a || b) {
c = 1;
} else {
c = 0;
}
Теперь, чтобы тест убил этого мутанта, должны быть выполнены следующие три условия:
- Тест должен достичь измененного утверждения.
- Входные данные теста должны влиять на состояние программы, вызывая разные состояния программы для мутанта и исходной программы. Например, тест с
a = 1
иb = 0
сделал бы это. - Неправильное состояние программы (значение «c») должно распространиться на выход программы и быть проверено тестом.
Эти условия в совокупности называются моделью RIP . [8]
Тестирование слабых мутаций (или слабое покрытие мутаций ) требует, чтобы были выполнены только первое и второе условия. Надежное тестирование мутаций требует соблюдения всех трех условий. Сильная мутация более эффективна, поскольку она гарантирует, что набор тестов действительно сможет выявить проблемы. Слабая мутация тесно связана с методами покрытия кода . Чтобы гарантировать, что набор тестов удовлетворяет требованиям слабого мутационного тестирования, требуется гораздо меньше вычислительной мощности, чем сильного мутационного тестирования.
Однако бывают случаи, когда невозможно найти тестовый пример, который мог бы убить этого мутанта. Полученная программа по поведению эквивалентна исходной. Такие мутанты называются эквивалентными мутантами .
Обнаружение эквивалентных мутантов является одним из самых больших препятствий для практического использования мутационного тестирования. Усилия, необходимые для проверки эквивалентности мутантов, могут быть очень высокими даже для небольших программ. [17] Систематический обзор литературы 2014 года, посвященный широкому спектру подходов к решению проблемы эквивалентных мутантов. [18] определил 17 соответствующих методов (в 22 статьях) и три категории методов: обнаружение (DEM); внушение (СЭМ); и избежание генерации эквивалентных мутантов (AEMG). Эксперимент показал, что мутации высшего порядка в целом и стратегия JudyDiffOp в частности обеспечивают многообещающий подход к проблеме эквивалентных мутантов.
В дополнение к эквивалентным мутантам существуют отнесенные к категории мутанты , которые представляют собой мутанты, которые существуют в том же месте исходного кода, что и другой мутант, и, как говорят, «отнесены» к другому мутанту. Включенные мутанты невидимы для инструмента тестирования мутаций и не влияют на показатели покрытия. Например, предположим, что у вас есть два мутанта, A и B, которые одинаково меняют строку кода. Мутант А тестируется первым, и в результате код работает неправильно. Затем тестируется мутант B, и результат тот же, что и в случае с мутантом A. В этом случае считается, что мутант B относится к мутанту A, поскольку результат тестирования мутанта B такой же, как и результат тестирования мутанта A. Поэтому Мутанта Б не нужно тестировать, так как результат будет таким же, как и Мутанта А.
Операторы мутации
[ редактировать ]При внесении синтаксических изменений в программу оператор мутации служит ориентиром, заменяющим части исходного кода. Учитывая, что мутации зависят от этих операторов, ученые создали набор операторов мутаций для разных языков программирования, таких как Java. Эффективность этих операторов мутации играет ключевую роль в тестировании мутаций. [19]
Многие операторы мутаций были исследованы исследователями. Вот несколько примеров операторов мутации для императивных языков:
- Удаление заявления
- Дублирование или вставка оператора, например
goto fail;
[20] - Замена логических подвыражений на true и false
- Замена одних арифметических операций другими, например
+
с*
,-
с/
- Замена некоторых логических отношений другими, например
>
с>=
,==
и<=
- Замена переменных другими из той же области действия (типы переменных должны быть совместимыми)
- Удалить тело метода. [21]
Эти операторы мутации также называются традиционными операторами мутации. Существуют также операторы мутации для объектно-ориентированных языков. [22] для параллельных конструкций, [23] сложные объекты, такие как контейнеры, [24] и т. д.
Типы операторов мутации
[ редактировать ]Операторы для контейнеров называются операторами мутации на уровне класса . Операторы на уровне класса изменяют структуру программы, добавляя, удаляя или изменяя проверяемые выражения. Для каждой категории изменений установлены конкретные операторы. [19] Например, инструмент muJava предлагает различные операторы мутации на уровне класса, такие как изменение модификатора доступа, вставка оператора приведения типа и удаление оператора приведения типа. Операторы мутации также были разработаны для тестирования уязвимостей безопасности программ. [25]
Помимо операторов уровня класса , MuJava также включает операторы мутации на уровне метода , называемые традиционными операторами. Эти традиционные операторы разработаны на основе функций, обычно встречающихся в процедурных языках. Они вносят изменения в операторы, добавляя, заменяя или удаляя примитивные операторы. Эти операторы делятся на шесть категорий: арифметические операторы , операторы отношения , условные операторы , операторы сдвига , логические операторы и операторы присваивания . [19]
Виды мутационного тестирования
[ редактировать ]Существует три типа мутационного тестирования;
Мутация заявления
[ редактировать ]Мутация операторов — это процесс, при котором блок кода намеренно изменяется путем удаления или копирования определенных операторов. Более того, он позволяет изменять порядок операторов внутри блока кода для создания различных последовательностей. [26] Этот метод имеет решающее значение при тестировании программного обеспечения, поскольку помогает выявить потенциальные слабости или ошибки в коде. Сознательно внося изменения в код и наблюдая за его поведением, разработчики могут обнаружить скрытые ошибки или недостатки, которые могут остаться незамеченными во время обычного тестирования. [27] Мутация операторов — это своего рода диагностический инструмент, который дает представление о надежности и отказоустойчивости кода, помогая программистам улучшить общее качество и надежность своего программного обеспечения.
Например, в приведенном ниже фрагменте кода удален весь раздел else:
function checkCredentials(username, password) {
if (username === "admin" && password === "password") {
return true;
}
}
Мутация значения
[ редактировать ]Мутация значений происходит, когда в коде выполняется модификация значений параметра и/или константы. Обычно это предполагает корректировку значений путем добавления или вычитания 1, но это также может включать в себя внесение более существенных изменений в значения. Конкретные изменения, вносимые во время мутации значений, включают два основных сценария:
Во-первых, происходит преобразование маленького значения в большее. Это влечет за собой замену маленького значения в коде на большее. Цель этого изменения — оценить, как код реагирует на более крупные входные данные. Это помогает гарантировать, что код сможет точно и эффективно обрабатывать эти большие значения, не встречая ошибок или неожиданных проблем. [26]
И наоборот, второй сценарий предполагает изменение более высокого значения на меньшее. В этом случае мы заменяем более высокое значение в коде меньшим значением. Этот тест направлен на оценку того, как код обрабатывает меньшие входные данные. Обеспечение правильной работы кода при меньших значениях необходимо для предотвращения непредвиденных проблем или ошибок при работе с такими входными данными. [26]
Например:
// Original code
function multiplyByTwo(value) {
return value * 2;
}
// Value mutation: Small value to higher value
function multiplyByTwoMutation1(value) {
return value * 10;
}
// Value mutation: Higher value to small value
function multiplyByTwoMutation2(value) {
return value / 10;
}
Мутация решения
[ редактировать ]Тестирование мутации решений сосредоточено на выявлении ошибок проектирования в коде с особым упором на обнаружение недостатков или слабых мест в логике принятия решений программы. Этот метод предполагает намеренное изменение арифметических и логических операторов, чтобы выявить потенциальные проблемы. [26] Манипулируя этими операторами, разработчики могут систематически оценивать, как код реагирует на различные сценарии принятия решений. Этот процесс помогает гарантировать, что пути принятия решений программы являются надежными и точными, предотвращая дорогостоящие ошибки, которые могут возникнуть из-за ошибочной логики. Тестирование мутаций решений служит ценным инструментом в разработке программного обеспечения, позволяя разработчикам повысить надежность и эффективность сегментов кода, принимающих решения.
Например:
// Original code
function isPositive(number) {
return number > 0;
}
// Decision mutation: Changing the comparison operator
function isPositiveMutation1(number) {
return number >= 0;
}
// Decision mutation: Negating the result
function isPositiveMutation2(number) {
return !(number > 0);
}
См. также
[ редактировать ]- Создание ошибок (или посев ошибок)
- Тестирование на вменяемость
- Внесение неисправностей
Ссылки
[ редактировать ]- ^ Jump up to: а б с д Ричард А. ДеМилло, Ричард Дж. Липтон и Фред Г. Сэйворд. Советы по выбору тестовых данных: Помощь практикующему программисту. Компьютер IEEE, 11(4):34-41. Апрель 1978 года.
- ^ Остранд, Томас (2002), «Тестирование белого ящика» , Энциклопедия разработки программного обеспечения , Американское онкологическое общество, номер документа : 10.1002/0471028959.sof378 , ISBN 978-0-471-02895-6 , получено 16 марта 2021 г.
- ^ Мисра, С. (2003). «Оценка четырех методологий тестового покрытия белого ящика» . CCECE 2003 - Канадская конференция по электротехнике и вычислительной технике. На пути к заботливой и гуманной технологии (Кат. № 03CH37436) . Том. 3. Монреаль, Квебек, Канада: IEEE. стр. 1739–1742. дои : 10.1109/CCECE.2003.1226246 . ISBN 978-0-7803-7781-3 . S2CID 62549502 .
- ^ Jump up to: а б с Пол Амманн и Джефф Оффатт. Введение в тестирование программного обеспечения. Издательство Кембриджского университета, 2008.
- ^ Цзя, Юэ; Харман, Марк (сентябрь 2009 г.). «Анализ и обзор развития мутационного тестирования» (PDF) . Центр CREST, Королевский колледж Лондона, Технический отчет TR-09-06 . 37 (5): 649–678. дои : 10.1109/TSE.2010.62 . S2CID 6853229 . Архивировано из оригинала (PDF) 4 декабря 2017 г.
- ^ Дассо, Аристид; Фунес, Ана (2007). Верификация, валидация и тестирование в разработке программного обеспечения . Idea Group Inc. ISBN 978-1591408512 .
- ^ Jump up to: а б Смит Б., «О рекомендациях по расширению набора автоматизированных тестов с помощью анализа мутаций», 2008 г.
- ^ Jump up to: а б Мутация 2000: объединение ортогональных. Архивировано 28 сентября 2011 г. в Wayback Machine А. Джефферсоном Оффуттом и Роландом Х. Унтчем.
- ^ Тим А. Бадд, Мутационный анализ данных тестирования программы. Докторская диссертация, Йельский университет, Нью-Хейвен, Коннектикут, 1980 г.
- ^ Каксонен, Раули. Функциональный метод оценки безопасности реализации протокола (лицензиатская диссертация). Эспоо. 2001.
- ^ А. Джефферсон Оффатт. 1992. Исследования эффекта связи тестирования программного обеспечения. АКМ Транс. Программное обеспечение англ. Методол. 1, 1 (январь 1992 г.), 5–20.
- ^ А. Т. Акри, Т. А. Бадд, Р. А. Демилло, Р. Дж. Липтон и Ф. Г. Сэйворд, «Анализ мутаций», Технологический институт Джорджии, Атланта, Джорджия, Технический отчет GIT-ICS-79/08, 1979.
- ^ Юэ Цзя; Харман, М., «Построение тонких ошибок с использованием тестирования мутаций более высокого порядка», Анализ и манипулирование исходным кодом, 2008 г. Восьмая международная рабочая конференция IEEE, том, №, стр. 249, 258, 28-29 сентября 2008 г.
- ^ Марьям Умар, «Оценка операторов мутации для эквивалентных мутантов», диссертация MS, 2006 г.
- ^ Поло М. и Пиаттини М., «Тестирование мутаций: практические аспекты и анализ затрат», Университет Кастилии-Ла-Манча (Испания), презентация, 2009 г.
- ^ Андерсон С., «Тестирование мутаций», Эдинбургский университет, Школа информатики, презентация, 2011 г.
- ^ П.Г. Франкл, С.Н. Вайс и К. Ху. Универсальное тестирование против мутационного тестирования: экспериментальное сравнение эффективности. Журнал систем и программного обеспечения , 38:235–253, 1997.
- ^ Преодоление проблемы эквивалентного мутанта: систематический обзор литературы и сравнительный эксперимент по мутации второго порядка, авторы Л. Мадейски, В. Ожешина, Р. Торкар, М. Юзала. Транзакции IEEE по разработке программного обеспечения
- ^ Jump up to: а б с Хамимун, Сукаина; Фалах, Бушаиб (24 сентября 2016 г.). «Методы тестирования мутаций: сравнительное исследование». 2016 Международная конференция по инженерии и MIS (ICEMIS) . стр. 1–9. дои : 10.1109/ICEMIS.2016.7745368 . ISBN 978-1-5090-5579-1 . S2CID 24301702 . Архивировано из оригинала 19 июня 2018 года . Проверено 8 октября 2023 г.
{{cite book}}
: CS1 maint: bot: исходный статус URL неизвестен ( ссылка ) - ^ Ошибка Apple SSL/TLS, автор Адам Лэнгли.
- ^ Нидермайр, Райнер; Юргенс, Эльмар; Вагнер, Стефан (14 мая 2016 г.). «Скажут ли мне мои тесты, если я взломаю этот код?» . Материалы международного семинара по непрерывной эволюции и доставке программного обеспечения . ЦСЭД '16. Остин, Техас: Ассоциация вычислительной техники. стр. 23–29. arXiv : 1611.07163 . дои : 10.1145/2896941.2896944 . ISBN 978-1-4503-4157-8 . S2CID 9213147 .
- ^ MuJava: автоматизированная система мутации классов. Архивировано 11 марта 2012 г. в Wayback Machine Ю-Сын Ма, Джеффом Оффаттом и Ён Рэ Кво.
- ^ Операторы мутации для Concurrent Java (J2SE 5.0) , Джереми С. Брэдбери, Джеймс Р. Корди, Юрген Дингель.
- ^ Мутация объектов Java Роджера Т. Александра, Джеймса М. Бимана, Судипто Гоша, Биксиа Джи.
- ^ Тестирование переполнения буфера, SQL-инъекций и ошибок форматной строки на основе мутаций, авторы: Х. Шахриар и М. Зулькернин.
- ^ Jump up to: а б с д Уолтерс, Эми (01 июня 2023 г.). «Понимание мутационного тестирования: подробное руководство» . testRigor Инструмент автоматического тестирования на основе искусственного интеллекта . Проверено 8 октября 2023 г.
- ^ Дэн, Лин; Оффатт, Джефф; Ли, Нан (22 марта 2013 г.). «Эмпирическая оценка оператора мутации удаления оператора». 2013 Шестая международная конференция IEEE по тестированию, верификации и валидации программного обеспечения . стр. 84–93. дои : 10.1109/ICST.2013.20 . ISBN 978-0-7695-4968-2 . ISSN 2159-4848 . S2CID 12866713 . Проверено 8 октября 2023 г.