Статья написана на основе поста в telegram-канале Cross Join.


Прежде чем рассказать об этом подходе сначала в двух словах объясню, что такое мутационное тестирование вообще. Для тех, кто не в курсе.


Мутационное тестирование


Когда вы пишете тесты, по TDD или нет, даже с формальным 100% покрытием, вы никогда не будете уверены в том, что в коде на самом деле протестировано всё. Например, можно банально ошибиться в вызове assert в самом тесте.


assertEquals($a, $a);

И если даже при тестировании удалось дойти до какого-то if, не факт, что в этом if правильно проверены все условия.


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


Например, заменили плюс на минус, или добавили "не" к условию, и смотрите, отреагировали ли тесты. Такой подход называется "Мутационное тестирование".


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


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


Проблема в этом подходе в том, что это довольно муторно настраивается, много нюансов, как описать, что надо мутировать, что нет. И всё это  потребляет дикое количество ресурсов: разбор кода в AST, мутирование и обратное преобразование. 


Mutation Driven Development


Сейчас некоторые авторы предлагают подход mutation driven development. Он аналогичен TDD, но как бы наоборот. 


  1. сначала добавляете новый код в проект
  2. временно вносите баг
  3. пишете тест, который ловит этот баг (или фиксите старые тесты)
  4. переходите к следующей строке (или к следующей части условия if). Конечно, и здесь можно случайно пропустить кусок логики, но в целом MDD (?) гораздо более упорот, чем 100% сoverage или TDD.

Для меня такой подход видится интересным тем, что можно ничего не настраивать в CI, не просить выделить доп ресурсы для обработки пайплайнов, а просто писать более покрытый код, даже если тимлиду или вообще никому в твоей команде в целом MDD неинтересен. 


Конечно, это не бесплатно, и нещадно пожирает ресурсы программиста. Имхо mutation driven testing можно и нужно применять только там, где есть ответственная логика. Работа с деньгами, медицинский софт и т.д. Понятно, что на эндпоинт, выдающий текущую погоду или прочую ерунду, можно не тратить ресурсы, как ручные, так и автоматические.Вообще, множество проектов содержат 95% стандартного бойлерплейта, и лишь чуть-чуть важной бизнес-логики. Вот эту важную логику при желании можно довести до состояния, близкого к идеалу.


Конечно же мы обсудим mutation driven development в одном из ближайших выпусков "Цинкового прода", не забудьте подписаться на подкаст