Разделы портала

Онлайн-тренинги

.
Начинаем работу с мутационным тестированием
13.07.2026 00:00

Автор: Баз Дейкстра (Bas Dijkstra)
Оригинал статьи
Перевод: Ольга Алифанова

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

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

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

Expected: banana, actual: strawberry

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

Никогда не доверяйте тесту, который не видели падающим

Думаю, эта мысль становится ещё более актуальной и важной, когда тесты пишете не вы сами, а передаёте эту задачу программному обеспечению. Это может быть инструмент модельно-ориентированного тестирования, генерирующий тесты на основе созданной модели системы, но в наши дни чаще всего это будет LLM, генерирующая тесты. Действительно таким тестам можно доверять? На чём это доверие основано? Известно ли, способны ли эти тесты вообще падать?

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

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

Если вам нужны примеры мутационного тестирования в действии, вот несколько моих предыдущих статей, где они есть:

  • Вот одна, где объясняется, что мутационное тестирование не ограничивается юнит-тестами
  • Вот ещё одна, где я показываю, как использую мутационное тестирование для анализа и улучшения тестов для RestAssured.Net

И да, если хочется получить практический опыт с тестированием мутациями, я также провожу воркшоп по этой теме.

Теперь, когда вам понятно, что это такое и как работает, с чего и где начинать? Как я уже говорил, тема мутационного тестирования всё чаще всплывает в разговорах с тестировщиками и клиентами, и обычно я рекомендую следующее:

  1. Определите небольшой, но важный участок кода в продукте — код, который, как считается, должен быть хорошо покрыт тестами. Отлично подходят классы, содержащие реализацию важной бизнес-логики.
  2. Определите тесты, покрывающие этот участок. Как уже упоминалось в статье выше, это могут быть юнит-, интеграционные или даже end-to-end тесты, но чем медленнее тесты, тем дольше будет выполняться мутационное тестирование и тем длиннее будет цикл обратной связи.
  3. Настройте выбранный инструмент мутационного тестирования так, чтобы он вносил изменения в выбранный участок кода и запускал нужные тесты. Большинство популярных инструментов, включая Stryker для JavaScript и .NET и PIT для Java, делают это достаточно просто.
  4. Проанализируйте отчёт, созданный инструментом, и посмотрите, где обнаружены возможности для улучшения тестов. Если такие есть, внесите изменения, запустите тестирование мутаций снова и проверьте, улучшился ли результат, то есть увеличилось ли покрытие мутаций.

Кстати, о покрытии мутаций: как и любые другие метрики покрытия, это не панацея. Не рекомендую стремиться к какому-то конкретному проценту покрытия мутаций, потому что это может привести к написанию тестов ради самих тестов, а не ради получения полезной обратной связи. Лучше запускать тестирование мутаций периодически и отслеживать динамику показателя. Если он растёт — скорее всего, всё делается правильно. Если падает — стоит обратить на это внимание.

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

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

Это не значит, что мутационному тестированию никогда не найдется место в пайплайне, но на ранних этапах его внедрения включать его туда не рекомендую.

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

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

P.S.: тестирование мутациями будет одной из тем, которые мы подробнее разберём в моём новом курсе «Valuable feedback, fast». Этот курс объединяет множество уроков, которые я извлёк, и советов по успешному внедрению автоматизации тестирования, всё на основе реалистичного кейса, где предстоит помочь компании внедрить автоматизацию, дающую, как можно догадаться, ценную обратную связь — быстро.

Обсудить в форуме