Весь покрытый тестами, абсолютно весь
Компания Agitar Software предлагает довольно любопытную метрику для оценки качества программного кода. Формула с недвусмысленным названием CRAP позволяет оценить, воскликнет ли разработчик «Oh crap!» узнав, что за код ему выпало счастье поддерживать.
Конечно же, не существует абсолютно достоверного способа определить, является ли определенный кусок кода «crappy» или нет. Однако интуитивно понятно, что такой отзыв, скорее всего, получит неоправданно сложный, запутанный код. А поскольку написание автоматизированных тестов (например, с помощью JUnit или PHPUnit) для запутанного кода — вещь нетривиальная, он обычно оказывается не покрыт тестами вовсе. Наличие unit-тестов означает не только контроль за работоспособностью кода, но и более понятную архитектуру приложения, а также то, что разработчики в своё время позаботились о затратах на поддержку.
Как это работает
Если вдаваться в математику, величина CRAP (Change Risk Analysis and Prediction) для отдельно взятого метода m вычисляется по формуле:
CRAP(m) = comp(m)^2 * (1 – cov(m)/100)^3 + comp(m)
где comp(m) — так называемая цикломатическая сложность метода m, определяемая как число путей внутри метода плюс единица, а cov(m) — процент покрытие кода тестами.
Другими словами, низкий CRAP-индекс означает относительно небольшой риск при изменении кода: код несложный и его работоспособность достаточно хорошо контролируется тестами. Высокий индекс говорит о том, что вносить изменения довольно рискованно: сложность кода в сумме с небольшим количеством тестов дают довольно опасную комбинацию, можно быть уверенным, что-нибудь сломается в самом непредсказуемом месте. Таким образом, понизить CRAP-индекс можно либо написанием unit-тестов для сложных участков кода, либо с помощью рефакторинга эту сложность уменьшить. Предпочтительней, разумеется, и то, и другое, поскольку наличие тестов помогает избежать ошибок при рефакторинге.
Crap4j
Пока существует только одна реализация CRAP-формулы, в виде Eclipse-плагина crap4j для Java. По признанию самих разработчиков, все пороговые значения чисто экспериментальны. CRAP-индекс отдельно взятого метода может варьироваться от 1 (для метода сложности 1, покрытого тестами на 100%) до довольно внушительных цифр (например, метод сложностью 100 без единого теста получит 10 100 баллов). Было решено, для начала, использовать порог в 30 баллов как границу, с которой начинается crappy-код. Например, методы со сложностью 10, на 75% покрытые тестами, ещё не рассматриваются как crap, также как и методы со сложностью 2 без тестов вообще.
На уровне проекта, статистика показывает процент методов с crap-индексом выше 30. Проект может иметь до 5% таких методов (впрочем, ничто не мешает принять свои собственные пороговые значения). Кроме этого, crap4j показывает так называемый CRAP load — это оценка объема работ, необходимых для исправления crappy-методов, учитывающая недостающее количество тестов и необходимый для их написания рефакторинг.
Как и любая из существующих метрик, CRAP, разумеется, не идеален. Код может быть полностью покрыт никуда не годными тестами, или содержать сложный метод, который, тем не менее, легче для понимания, чем 3 более простых. Не учитываются более высокоуровневые метрики, ориентированные на архитектуру приложения (такие как coupling и cohesion). Тем не менее, формула даёт достаточно полезной информации и обширное поле для экспериментов.
Crap4j Home | Eclipse Update Site | Enjoy!
Ещё по теме:
Pardon My French, But This Code Is CRAP
The Code CRAP Metric Hits the Fan — Introducing the crap4j Plug-in