Полезно ли тестирование мутаций на практике?

У вас есть примеры реальных тестов на мутации? Работает ли он лучше, чем простые тестовые инструменты? Или это бесполезно?

Каковы преимущества / недостатки мутационного тестирования в реальном мире?

12 ответов

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

Это двухэтапный процесс:

  1. Генерация мутантов.
  2. Проверьте, что мутации найдены тестами.

Я написал целую статью об этом процессе, включая некоторые конкретные случаи.

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

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

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

Дядя Боб, мутирующий тестовый пост

Я поиграл с питстом для небольшого, надуманного приложения:

http://pitest.org/

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

http://www.eclemma.org/

Для покрытия.


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

Мутационное тестирование - это угол атаки, который сильно отличается от методик модульного / функционального / интеграционного тестирования.

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

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

Например, когда вы получаете отчет, в котором говорится, что "ни один мутант не был убит тестовым примером x", вы смотрите, и оказывается, что утверждение было закомментировано.

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

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

Недавно я провел несколько исследований по мутации. Результаты здесь:

http://abeletsky.blogspot.com/2010/07/using-of-mutation-testing-in-real.html

Вкратце: тестирование на мутации может дать некоторую информацию о качестве исходного кода и тестов, но это не то, что просто использовать.

Недавно я начал практиковать тестирование мутаций в C++, и это намного лучше, чем покрытие кода. В крайнем случае, возможно иметь 100% покрытия кода и 0% потенциальных обнаруженных ошибок (в моем случае это выявило ~80% поддельных ошибок) - конечно, это зависит от того, насколько хорошо вы генерируете ошибки,

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

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

Мутационное тестирование помогло мне в двух конкретных проектах:

  • Небольшая библиотека, разработанная мной: я использовал мутационное тестирование для проверки качества своих тестов. Я обнаружил, что даже при «строгом TDD» у меня были выжившие мутанты. Это помогло мне понять некоторые антипаттерны в моем стиле тестирования. Я даже включил анализ тестирования мутаций как часть CI (только при слиянии с основной веткой). Но я мог это сделать, потому что библиотека крошечная и не имела никаких зависимостей. Код был простым и быстрым, и все тесты были модульными тестами (всего около 300).

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

В этих проектах я использовал Stryker (для JS и TS) и был доволен результатами. Это помогло мне показать, как работает мутационное тестирование людям, которые об этом не знали.

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

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

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

Если ты примешь это

а) Необходимы модульные тесты

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

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

г) Модульный тест сам по себе должен быть протестирован, т.е. показан провал в соответствующих сценариях (обратите внимание, именно этого пытается достичь TDD Red-Green-Refactor)

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

Я настроил тестирование мутаций на Angular, используя https://stryker-mutator.io/docs/stryker-js/guides/angular/, просто для экспериментов, и мне потребовалось 2 часа, чтобы получить отчет для одного файла кода. Тем не менее, я был очень доволен опытом использования Stryker с .NET. Должен признать, что я новичок в тестировании мутаций, и могут быть инструменты получше, которые работают с Angular / karma, но о производительности нужно помнить, особенно если вы планируете использовать ее вместе с TDD.

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

https://pedrorijo.com/blog/intro-mutation/

My own experience shows that Pitest is pretty useful, but since the runtime explodes it works only one very fast test sets. In practice this limits where I apply mutation testing.

Тестовый пример для первого ведет себя по-другому из-за вышеупомянутой мутации, теперь возникло исключение. Таким образом, он не возвращает ожидаемый массив {6,3}. Однако наш второй тестовый пример остается таким же, потому что он также включает положительное число. Таким образом, это также дает исключение для положительных чисел. Теперь, если нам нужно написать успешный тестовый пример, это будет Input ={-6,-6,-7,-3,-4}Expected = {-6,-3}

Другие вопросы по тегам