stringtranslate.com

Тестирование мутаций

Тестирование мутаций (или анализ мутаций или программная мутация ) используется для разработки новых программных тестов и оценки качества существующих программных тестов. Тестирование мутаций подразумевает внесение небольших изменений в программу. [1] Каждая мутировавшая версия называется мутантом , и тесты обнаруживают и отклоняют мутантов, заставляя поведение исходной версии отличаться от мутанта. Это называется уничтожением мутанта. Тестовые наборы измеряются процентом мутантов, которых они убивают. Новые тесты могут быть разработаны для уничтожения дополнительных мутантов. Мутанты основаны на четко определенных операторах мутаций , которые либо имитируют типичные ошибки программирования (например, использование неправильного оператора или имени переменной), либо заставляют создавать ценные тесты (например, деление каждого выражения на ноль). Цель состоит в том, чтобы помочь тестировщику разработать эффективные тесты или обнаружить слабые места в тестовых данных, используемых для программы, или в разделах кода, которые редко или никогда не используются во время выполнения . Тестирование мутаций является формой тестирования «белого ящика» . [2] [3]

Введение

Большая часть этой статьи посвящена «программной мутации», при которой программа изменяется. Более общее определение мутационного анализа — это использование четко определенных правил, определенных в синтаксических структурах, для внесения систематических изменений в программные артефакты. [4] Мутационный анализ применялся и к другим проблемам, но обычно применяется к тестированию. Таким образом, мутационное тестирование определяется как использование мутационного анализа для разработки новых программных тестов или оценки существующих программных тестов. [4] Таким образом, мутационный анализ и тестирование могут применяться для проектирования моделей, спецификаций, баз данных, тестов, XML и других типов программных артефактов, хотя программная мутация является наиболее распространенной. [5]

Обзор

Тесты могут быть созданы для проверки правильности реализации данной программной системы, но создание тестов все еще ставит вопрос о том, являются ли тесты правильными и в достаточной ли степени охватывают требования, которые инициировали реализацию. [6] (Эта технологическая проблема сама по себе является примером более глубокой философской проблемы под названием « Quis custodiet ipsos custodes? » [«Кто будет охранять охранников?»].) Идея, лежащая в основе мутационного тестирования, заключается в том, что если вводится мутант, это обычно вызывает ошибку в функциональности программы, которую должны найти тесты. Таким образом, тесты проверяются. Если мутант не обнаруживается набором тестов, это обычно означает, что набор тестов не может обнаружить ошибки, представленные мутантом, но это также может означать, что мутация не вносит никаких ошибок, то есть мутация является допустимым изменением, которое не влияет на функциональность. Один (распространенный) способ, которым мутант может быть допустимым, заключается в том, что измененный код является «мертвым кодом», который никогда не выполняется.

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

Цели

Цели мутационного тестирования многочисленны:

История

Тестирование мутаций было первоначально предложено Ричардом Липтоном, будучи студентом, в 1971 году [8], и впервые разработано и опубликовано Демилло, Липтоном и Сэйвордом. [1] Первая реализация инструмента тестирования мутаций была осуществлена ​​Тимоти Баддом в рамках его докторской работы (под названием «Анализ мутаций» ) в 1980 году в Йельском университете . [9]

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

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

Фаззинг можно считать особым случаем мутационного тестирования. При фаззинге сообщения или данные, которыми обмениваются внутри интерфейсов связи (как внутри, так и между экземплярами ПО), мутируют для обнаружения сбоев или различий в обработке данных. Codenomicon [10] (2001) и Mu Dynamics (2005) развили концепции фаззинга до полностью статистической платформы мутационного тестирования, укомплектованной мониторами для тщательной проверки реализаций протоколов.

Обзор тестирования мутаций

Тестирование мутаций основано на двух гипотезах. Первая — гипотеза компетентного программиста . Эта гипотеза утверждает, что компетентные программисты пишут программы, которые близки к правильным. [1] «Близко» должно основываться на поведении, а не на синтаксисе. Вторая гипотеза называется эффектом сцепления . Эффект сцепления утверждает, что простые неисправности могут каскадироваться или объединяться , образуя другие возникающие неисправности. [11] [12]

Мутанты более высокого порядка также выявляют тонкие и важные ошибки, что дополнительно подтверждает эффект сцепления. [13] [14] [7] [15] [16] Мутанты более высокого порядка появляются благодаря созданию мутантов с более чем одной мутацией.

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

Например, рассмотрим следующий фрагмент кода C++:

если ( а && б ) { с = 1 ; } иначе { с = 0 ; }            

Оператор мутации условия заменит его &&на ||и создаст следующий мутант:

если ( а || б ) { с = 1 ; } иначе { с = 0 ; }            

Теперь, чтобы тест убил этого мутанта, должны быть выполнены следующие три условия:

  1. Тест должен достичь мутировавшего утверждения.
  2. Тестовые входные данные должны заражать состояние программы, вызывая различные состояния программы для мутанта и исходной программы. Например, тест с a = 1и b = 0будет делать это.
  3. Неправильное состояние программы (значение «c») должно распространяться на вывод программы и проверяться тестом.

Эти условия в совокупности называются моделью RIP . [8]

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

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

Обнаружение эквивалентных мутантов является одним из самых больших препятствий для практического использования мутационного тестирования. Усилия, необходимые для проверки эквивалентности мутантов, могут быть очень высокими даже для небольших программ. [17] Систематический обзор литературы 2014 года, посвященный широкому спектру подходов к решению проблемы эквивалентных мутантов [18], выявил 17 соответствующих методов (в 22 статьях) и три категории методов: обнаружение (DEM); предложение (SEM); и предотвращение генерации эквивалентных мутантов (AEMG). Эксперимент показал, что мутация высшего порядка в целом и стратегия JudyDiffOp в частности представляют собой многообещающий подход к проблеме эквивалентных мутантов.

В дополнение к эквивалентным мутантам существуют подчиненные мутанты , которые являются мутантами, которые существуют в том же месте исходного кода, что и другой мутант, и которые, как говорят, «подчинены» другим мутантом. Подчиненные мутанты не видны инструменту тестирования мутаций и не вносят вклад в метрики покрытия. Например, предположим, что у вас есть два мутанта, A и B, которые оба изменяют строку кода одинаковым образом. Сначала тестируется мутант A, и результатом является то, что код работает неправильно. Затем тестируется мутант B, и результат тот же, что и у мутанта A. В этом случае мутант B считается подчиненным мутантом A, поскольку результат тестирования мутанта B такой же, как результат тестирования мутанта A. Следовательно, мутант B не нужно тестировать, так как результат будет таким же, как у мутанта A.

Операторы мутации

Чтобы внести синтаксические изменения в программу, оператор мутации служит в качестве руководства, которое заменяет части исходного кода. Учитывая, что мутации зависят от этих операторов, ученые создали коллекцию операторов мутации для адаптации к различным языкам программирования, таким как Java. Эффективность этих операторов мутации играет ключевую роль в тестировании мутаций. [19]

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

Эти операторы мутации также называются традиционными операторами мутации. Существуют также операторы мутации для объектно-ориентированных языков, [22] для параллельных конструкций, [23] сложных объектов, таких как контейнеры, [24] и т. д.

Типы операторов мутации

Операторы для контейнеров называются операторами мутации на уровне класса . Операторы на уровне класса изменяют структуру программы, добавляя, удаляя или изменяя проверяемые выражения. Для каждой категории изменений были установлены специальные операторы. [19] Например, инструмент muJava предлагает различные операторы мутации на уровне класса, такие как Access Modifier Change, Type Cast Operator Insertion и Type Cast Operator Deletion. Операторы мутации также были разработаны для выполнения тестирования уязвимостей безопасности программ. [25]

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

Типы мутационного тестирования

Существует три типа тестирования на мутации:

Мутация заявления

Мутация операторов — это процесс, при котором блок кода намеренно изменяется путем удаления или копирования определенных операторов. Более того, он позволяет переупорядочивать операторы в блоке кода для генерации различных последовательностей. [26] Этот метод имеет решающее значение в тестировании программного обеспечения, поскольку он помогает выявлять потенциальные слабые места или ошибки в коде. Намеренно внося изменения в код и наблюдая за его поведением, разработчики могут обнаружить скрытые ошибки или изъяны, которые могут остаться незамеченными во время обычного тестирования. [27] Мутация операторов — это диагностический инструмент, который дает представление о надежности и устойчивости кода, помогая программистам улучшить общее качество и надежность своего программного обеспечения.

Например, в приведенном ниже фрагменте кода удален весь раздел «else»:

функция checkCredentials ( имя пользователя , пароль ) { если ( имя пользователя === "admin" && пароль === "пароль" ) { вернуть true ; } }                

Мутация ценности

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

Во-первых, есть преобразование от малого значения к большему значению. Это влечет за собой замену малого значения в коде на большее. Цель этого изменения — оценить, как код реагирует, когда он сталкивается с большими входными данными. Это помогает гарантировать, что код может точно и эффективно обрабатывать эти большие значения, не сталкиваясь с ошибками или неожиданными проблемами. [26]

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

Например:

// Исходный код function multiplyByTwo ( value ) { return value * 2 ; }      // Мутация значения: от меньшего значения к большему function multiplyByTwoMutation1 ( value ) { return value * 10 ; }      // Мутация значения: большее значение к меньшему значению function multiplyByTwoMutation2 ( value ) { return value / 10 ; }      

Мутация решения

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

Например:

// Исходный код function isPositive ( number ) { return number > 0 ; }      // Решение мутации: Изменение оператора сравнения function isPositiveMutation1 ( number ) { return number >= 0 ; }      // Решение мутации: отрицание результата function isPositiveMutation2 ( number ) { return ! ( number > 0 ); }      

Фреймворки, реализующие мутационное тестирование

Смотрите также

Ссылки

  1. ^ abcd Ричард А. Демилло, Ричард Дж. Липтон и Фред Г. Сэйворд. Советы по выбору тестовых данных: Помощь практикующему программисту. IEEE Computer, 11(4):34-41. Апрель 1978 г.
  2. ^ Остранд, Томас (2002), «Тестирование методом белого ящика», Энциклопедия программной инженерии , Американское онкологическое общество, doi :10.1002/0471028959.sof378, ISBN 978-0-471-02895-6, получено 2021-03-16
  3. ^ Misra, S. (2003). "Оценка четырех методологий покрытия тестами белого ящика". CCECE 2003 - Канадская конференция по электротехнике и вычислительной технике. На пути к заботливым и гуманным технологиям (Кат. № 03CH37436) . Том 3. Монреаль, Квебек, Канада: IEEE. стр. 1739–1742. doi :10.1109/CCECE.2003.1226246. ISBN 978-0-7803-7781-3. S2CID  62549502.
  4. ^ abc Пол Амманн и Джефф Оффатт. Введение в тестирование программного обеспечения. Cambridge University Press, 2008.
  5. ^ Цзя, Юэ; Харман, Марк (сентябрь 2009 г.). «Анализ и обзор развития тестирования мутаций» (PDF) . Центр CREST, Королевский колледж Лондона, Технический отчет TR-09-06 . 37 (5): 649–678. doi :10.1109/TSE.2010.62. S2CID  6853229. Архивировано из оригинала (PDF) 2017-12-04.
  6. ^ Дассо, Аристидес; Фунес, Ана (2007). Верификация, валидация и тестирование в программной инженерии . Idea Group Inc. ISBN 978-1591408512.
  7. ^ ab Smith B., «О руководстве по расширению автоматизированного набора тестов с помощью анализа мутаций», 2008 г.
  8. ^ ab Мутация 2000: Объединение ортогонального Архивировано 28 сентября 2011 г. в Wayback Machine А. Джефферсоном Оффуттом и Роландом Х. Антчем.
  9. ^ Тим А. Бадд, Мутационный анализ данных тестовых программ. Кандидатская диссертация, Йельский университет, Нью-Хейвен, Коннектикут, 1980.
  10. ^ Каксонен, Раули. Функциональный метод оценки безопасности реализации протокола (диссертация). Эспоо. 2001.
  11. ^ А. Джефферсон Оффатт. 1992. Исследования эффекта связи при тестировании программного обеспечения. ACM Trans. Softw. Eng. Methodol. 1, 1 (январь 1992), 5-20.
  12. ^ AT Acree, TA Budd, RA DeMillo, RJ Lipton и FG Sayward, «Анализ мутаций», Технологический институт Джорджии, Атланта, Джорджия, Технический отчет GIT-ICS-79/08, 1979.
  13. ^ Юэ Цзя; Харман, М., «Построение тонких неисправностей с использованием тестирования мутаций высшего порядка», Анализ исходного кода и манипуляция, 2008 г. Восьмая международная рабочая конференция IEEE по , т., №, стр. 249, 258, 28–29 сентября 2008 г.
  14. ^ Марьям Умар, «Оценка операторов мутации для эквивалентных мутантов», диссертация магистра наук, 2006 г.
  15. ^ Поло М. и Пьяттини М., «Тестирование мутаций: практические аспекты и анализ затрат», Университет Кастилья-Ла-Манча (Испания), Презентация, 2009 г.
  16. ^ Андерсон С., «Тестирование мутаций», Эдинбургский университет, Школа информатики, Презентация, 2011 г.
  17. ^ PG Frankl, SN Weiss и C. Hu. Универсальное использование против мутационного тестирования: экспериментальное сравнение эффективности. Журнал систем и программного обеспечения , 38:235–253, 1997.
  18. ^ Преодоление проблемы эквивалентных мутаций: систематический обзор литературы и сравнительный эксперимент по мутации второго порядка Л. Мадейски, В. Ожешина, Р. Торкар, М. Йозала. Труды IEEE по программной инженерии
  19. ^ abc Hamimoune, Soukaina; Falah, Bouchaib (24 сентября 2016 г.). «Методы тестирования мутаций: сравнительное исследование». Международная конференция по инжинирингу и MIS (ICEMIS) 2016 г. стр. 1–9. doi :10.1109/ICEMIS.2016.7745368. ISBN 978-1-5090-5579-1. S2CID  24301702. Архивировано из оригинала 19 июня 2018 г. Получено 2023-10-08 .{{cite book}}: CS1 maint: бот: исходный статус URL неизвестен ( ссылка )
  20. ^ Ошибка Apple SSL/TLS, Адам Лэнгли.
  21. ^ Нидермайер, Райнер; Юргенс, Элмар; Вагнер, Стефан (2016-05-14). «Скажут ли мне мои тесты, сломаю ли я этот код?». Труды Международного семинара по непрерывной эволюции и доставке программного обеспечения . CSED '16. Остин, Техас: Ассоциация вычислительной техники. стр. 23–29. arXiv : 1611.07163 . doi :10.1145/2896941.2896944. ISBN 978-1-4503-4157-8. S2CID  9213147.
  22. MuJava: Автоматизированная система мутации классов. Архивировано 11 марта 2012 г. на Wayback Machine Ю-Сын Ма, Джеффом Оффуттом и Ён Рэ Кво.
  23. ^ Операторы мутации для параллельной Java (J2SE 5.0) Джереми С. Брэдбери, Джеймс Р. Корди, Юрген Дингель.
  24. ^ Мутация объектов Java Роджера Т. Александра, Джеймса М. Бимана, Судипто Гоша, Биксии Джи.
  25. ^ Тестирование переполнений буфера, SQL-инъекций и ошибок форматирования строк на основе мутаций, Х. Шахриар и М. Зулькернин.
  26. ^ abcd Уолтерс, Эми (2023-06-01). «Понимание мутационного тестирования: всеобъемлющее руководство». testRigor Инструмент автоматизированного тестирования на основе ИИ . Получено 2023-10-08 .
  27. ^ Дэн, Лин; Оффатт, Джефф; Ли, Нан (22 марта 2013 г.). «Эмпирическая оценка оператора мутации удаления операторов». Шестая международная конференция IEEE по тестированию, верификации и валидации программного обеспечения 2013 г. стр. 84–93. doi :10.1109/ICST.2013.20. ISBN 978-0-7695-4968-2. ISSN  2159-4848. S2CID  12866713 . Получено 2023-10-08 .