Статья написана на основе поста в telegram-канале Cross Join.
Прежде чем рассказать об этом подходе сначала в двух словах объясню, что такое мутационное тестирование вообще. Для тех, кто не в курсе.
Мутационное тестирование
Когда вы пишете тесты, по TDD или нет, даже с формальным 100% покрытием, вы никогда не будете уверены в том, что в коде на самом деле протестировано всё. Например, можно банально ошибиться в вызове assert в самом тесте.
assertEquals($a, $a);
И если даже при тестировании удалось дойти до какого-то if, не факт, что в этом if правильно проверены все условия.
Чтобы убедиться в том, что тесты реально тестируют, есть такой способ: самому вносить в код баги, и смотреть, валятся ли от этого тесты. Если тесты по-прежнему зелёные при явном баге, значит протестировано не всё.
Например, заменили плюс на минус, или добавили "не" к условию, и смотрите, отреагировали ли тесты. Такой подход называется "Мутационное тестирование".
Обычно это делают в очень ответственных областях программирования, где ошибки вообще не допустимы. Например, софт марсохода или медицинское ПО.
Конечно в марсоходостроении это все делается автоматически: специальный инструмент уродует вашу программу и смотрит, слетели ли тесты.
Проблема в этом подходе в том, что это довольно муторно настраивается, много нюансов, как описать, что надо мутировать, что нет. И всё это потребляет дикое количество ресурсов: разбор кода в AST, мутирование и обратное преобразование.
Mutation Driven Development
Сейчас некоторые авторы предлагают подход mutation driven development. Он аналогичен TDD, но как бы наоборот.
- сначала добавляете новый код в проект
- временно вносите баг
- пишете тест, который ловит этот баг (или фиксите старые тесты)
- переходите к следующей строке (или к следующей части условия if). Конечно, и здесь можно случайно пропустить кусок логики, но в целом MDD (?) гораздо более упорот, чем 100% сoverage или TDD.
Для меня такой подход видится интересным тем, что можно ничего не настраивать в CI, не просить выделить доп ресурсы для обработки пайплайнов, а просто писать более покрытый код, даже если тимлиду или вообще никому в твоей команде в целом MDD неинтересен.
Конечно, это не бесплатно, и нещадно пожирает ресурсы программиста. Имхо mutation driven testing можно и нужно применять только там, где есть ответственная логика. Работа с деньгами, медицинский софт и т.д. Понятно, что на эндпоинт, выдающий текущую погоду или прочую ерунду, можно не тратить ресурсы, как ручные, так и автоматические.Вообще, множество проектов содержат 95% стандартного бойлерплейта, и лишь чуть-чуть важной бизнес-логики. Вот эту важную логику при желании можно довести до состояния, близкого к идеалу.
Конечно же мы обсудим mutation driven development в одном из ближайших выпусков "Цинкового прода", не забудьте подписаться на подкаст