Мутационное тестирование
Юнит-тесты помогают убедиться, что код работает так, как мы хотим. Но насколько сами тесты надёжны? Если удалить все assert-строки или заменить их на assertSame(1, 1), code coverage останется 100% — а тесты не проверят ничего. Мутационное тестирование отвечает на вопрос: «Насколько хороши наши тесты?»
Определение
Мутационное тестирование (Mutation Testing) — вид тестирования методом белого ящика, при котором в исходный код намеренно вносятся небольшие изменения (мутации), после чего проверяется, упадут ли существующие тесты. Если тесты проходят несмотря на изменение логики — тест-суит неэффективен.
Ключевая метрика — Mutation Score Indicator (MSI):
MSI = Killed Mutants / Valid Mutants × 100%Цель — максимально высокий MSI: большинство мутантов должны быть «убиты» тестами.
Типы мутаций
Мутация значений (Value mutation) — изменение константы или параметра (
5→0)Мутация операторов (Statement mutation) — удаление или замена оператора (
return x→return null)Мутация решения (Decision mutation) — замена логических операторов (
>→>=,&&→||)
Виды мутантов
Убитые (Killed) — тест упал после мутации; хорошо, тест работает
Выжившие (Survived) — тест прошёл несмотря на мутацию; плохо, нужна дополнительная проверка
Эквивалентные (Equivalent) — мутация не меняет поведение программы; не влияют на MSI
Timeout — мутант привёл к бесконечному циклу; считается обнаруженным
Нет покрытия (No Coverage) — мутант в коде, не покрытом тестами
Инструменты мутационного тестирования
Stryker (JavaScript / TypeScript)
Stryker — самый популярный инструмент мутационного тестирования для JavaScript/TypeScript. Поддерживает Jest, Mocha, Karma, Jasmine. Генерирует детальные HTML-отчёты с диффом мутаций.
Особенности:
Инкрементальный режим — пересчитывает только мутантов в изменённых файлах
Поддержка TypeScript, JavaScript, React, Vue
Dashboard для отслеживания MSI в CI
PIT / Pitest (Java)
PIT — стандарт мутационного тестирования для Java. Работает на уровне байткода (не исходников), что делает его существенно быстрее подходов на основе перекомпиляции. Интеграция с Maven и Gradle.
Особенности:
Работает с JUnit 4, JUnit 5, TestNG
Параллельный анализ мутантов
Интеграция с SonarQube
mutmut (Python)
mutmut — простой CLI-инструмент для Python. Минимальная настройка, хорошая интеграция с pytest.
Особенности:
Кэширует результаты между запусками
Подробный вывод: какие строки выжили
Сравнение инструментов
Stryker
JS/TS
Jest, Mocha, Karma
Средняя (AST)
HTML + Dashboard
PIT
Java
Maven, Gradle, JUnit
Быстрая (байткод)
HTML + XML
mutmut
Python
pytest
Медленная (исходники)
CLI + JSON
Infection
PHP
PHPUnit
Средняя
HTML + Text
Место в CI/CD
Мутационное тестирование ресурсоёмко — полный прогон на большой кодовой базе занимает часы. Рекомендуемый подход:
Запускать инкрементально (только изменённые файлы) в PR
Полный прогон — по расписанию (ночной/weekly)
Установить пороги в конфиге (Stryker
thresholds) и падать при снижении MSI
Источники
Дополнительные материалы
Mutation Testing (Google Testing Blog) — как Google применяет мутационное тестирование
What Is Mutation Testing: Tutorial With Examples — подробный гайд
Last updated