Что такое мутационное тестирование и какова его цель?

Ответ

Мутационное тестирование — это метод оценки качества набора тестов (например, юнит-тестов) путём внесения небольших, осмысленных изменений (мутаций) в исходный код и проверки, «отлавливают» ли эти изменения существующие тесты.

Цель: не тестировать сам код, а оценивать эффективность тестового покрытия. Хорошие тесты должны «убивать» мутации (т.е. падать), а выжившие мутации указывают на слабые места в тестах.

Как это работает (на примере):

  1. Исходный код:
    public int max(int a, int b) {
        if (a > b) {
            return a;
        }
        return b;
    }
  2. Мутант (изменение оператора > на >=):
    public int max(int a, int b) {
        if (a >= b) { // Мутация!
            return a;
        }
        return b;
    }
  3. Запускаются тесты. Если тест assertThat(max(5,5)).isEqualTo(5) отсутствует, мутант выживет (тесты пройдут), что покажет пробел в покрытии граничного случая (a == b).

Типы мутаций:

  • Изменение операторов: a > ba >= b, a + ba - b.
  • Изменение констант: return 0;return 1;.
  • Удаление вызовов методов: list.add(item); (ничего).
  • Изменение условий: if (cond)if (true) / if (false).

Инструменты для Java: PITest (Pitest) — наиболее популярный и практичный фреймворк. Интегрируется с Maven/Gradle и предоставляет детальный отчёт о выживших мутантах.

Преимущества:

  • Обнаруживает тесты, которые выполняют код, но не проверяют его логику (тесты-«пустышки»).
  • Побуждает писать более строгие и содержательные assertions.
  • Дополняет метрику coverage, которая показывает только выполнение строк, но не их проверку.

Недостатки: Вычислительно затратно, требует времени на анализ результатов.

Ответ 18+ 🔞

О, мутационное тестирование, блядь! Это ж такая штука, когда ты проверяешь не код, а свои же тесты, насколько они, сука, злые и внимательные. Представь: ты написал кучу юнит-тестов, они все зелёные, coverage 95%, и ты думаешь — ну я красавчик, блядь, всё покрыл, можно спать спокойно.

А вот нихуя, сука!

Суть в чём: берётся твой красивый код и в него начинают намеренно вносить мелкий пиздец. Меняют плюс на минус, > на >=, удаляют вызовы методов — короче, делают из него мутанта, уродца. И смотрят: а твои тесты, эти стражи порядка, заметят подмену? Зазвенят тревогой и убьют мутанта? Или пропустят его с милой улыбкой, сказав «всё ок»?

*Пример, чтобы не ебть мозг:**

Был у тебя метод, здоровый такой:

public int max(int a, int b) {
    if (a > b) {
        return a;
    }
    return b;
}

Приходит злой мутатор и говорит: «А давай-ка сделаем a >= b

public int max(int a, int b) {
    if (a >= b) { // Во, наебалово!
        return a;
    }
    return b;
}

И запускаются твои тесты. Если у тебя есть тест, который проверяет, что max(5,5) возвращает 5 — мутант получит пизды, тест упадёт. Всё хорошо, ты молодец.

А если такого теста нет? Мутант выживет, блядь! Тесты проглотят эту хуйню и скажут «окей». И это будет знак тебе, распиздяю: твои тесты — говно, они пропустили баг на ровном месте. Coverage был высокий, строки все выполнены, а по факту — нихуя не проверено.

Какие бывают мутации, этих уродцев:

  • Операторы подменили: + на -, && на ||, == на !=. Классика, блядь.
  • Константы поехали: return 0; стало return 1;. «Ну и хуй с ним, подумаешь, единица».
  • Вызов метода удалили: list.add(item) просто выкинули. А тест и не заметил, что в списке нихуя не добавилось.
  • Условия сломали: if (cond) заменили на if (true). Теперь код всегда лезет в одну ветку, а тестам похуй.

Чем это полезно, кроме как для мазохизма? Оно вытаскивает на свет божий тесты-пустышки, которые только код гоняют, но нихуя не assert'ят. Покрытие-то у них есть, а пользы — ноль. Заставляет писать настоящие проверки, а не просто вызывать методы для галочки.

Чем плохо? Да еба*ь, это долго, блядь! Запуск всех мутаций — это овердохуища итераций. Комп начинает гудеть как улей, а ты ждёшь. Но игра часто стоит свеч, особенно для критичных модулей.

Что юзать в Java? PITest (или просто Pit) — это, блядь, король мутационного тестирования. Интегрируется в Maven/Gradle, настраивается, и потом выдаёт тебе красивый отчёт, где всё разложено: вот тут мутанты выжили, вот тут ты их поубивал. Прям показывает, где твои тесты — хилая жопа, а где — стальные яйца.

Короче, если хочешь по-настоящему, блядь, проверить, не сосут ли твои тесты лапу, а делают дело — гоняй мутационное тестирование. Оно тебя быстро с небес на землю опустит, в рот меня чих-пых.