PHPUnit и C.R.A.P index - PullRequest
       45

PHPUnit и C.R.A.P index

13 голосов
/ 06 октября 2011

Я использую php undercontrol, и браузер кода сообщает о некоторой ошибке индекса CRAP на каждом сеттере / получателе, т.е. код, подобный этому

public function getFoo()
{
    return $this->_foo;
}

Метод получения / установки распространяется на модульное тестирование, сложность которого отсутствует, поскольку нет if / for / switch / foreach. так почему я получаю индекс CRAP 1 для этого кода ???

PS: автоответчик может быть вызван тем, что сложность отсутствует, но моя главная проблема заключается в том, что каждый получатель / установщик генерирует предупреждение из-за индекса CRAP, так что в любом случае нужно указать покрытие кода phpunit / php, чтобы сделать CRAP равным 0 для функции с индексом сложности 0.

Ответы [ 3 ]

28 голосов
/ 06 октября 2011

Минимальная оценка CRAP - 1, а не 0. Это потому, что алгоритм для CRAP -

CRAP(m) = comp(m)^2 * (1 – cov(m)/100)^3 + comp(m)

и минимальное значение цикломатической сложности (comp) для функции равно единице. Так что проблема не в phpunit, а в том, что помечает CRAP 1 как проблему.

В общем, вы хотите установить порог CRAP где-то около 5, где-нибудь ниже, и вы также можете просто использовать простую метрику покрытия кода (и стрелять на 100%), так как коэффициент сложности едва ли учитывается. CRAP> = 30 означает, что никакое количество испытаний не может сделать ваш метод не дрянным.

Цикломатическая сложность обычно (но существует более одного определения) может быть вычислена вручную как:

  • добавить 1 балл за вызов функции
  • добавить 1 балл за каждый цикл
  • добавить 1 балл за каждую ветку
1 голос
/ 06 октября 2011

Это действительно предупреждение?Обычно пороговое значение для предупреждений устанавливается намного выше 1 (возможно, около 30).Есть хороший пост SO здесь , который показывает, как рассчитывается число.Кажется, в моей настройке phpunit для CRAP есть несколько жестко закодированных значений 30.

Согласно Альберто Савойя , создателю индекса CRAP:

"CRAPИндекс (Анализ рисков и прогнозы изменений) предназначен для анализа и прогнозирования количества усилий, усилий и времени, необходимых для поддержания существующего объема кода. "

Минимальное число CRAP будет цикломатической сложностью для кодасо 100% покрытием.Идея состоит в том, что изменения в сложном коде с большей вероятностью создают проблемы, чем изменения в простом коде.

0 голосов
/ 26 июня 2019

CRAP это только показатель.Само по себе это примерно так же полезно, как "Как долго кусок строки?"кроме того, что это вопрос с неопределенным ответом, это также ответ с неопределенным вопросом.

Если вы знаете, что он измеряет, вы можете использовать его в качестве основного показателя сложности.Чтобы использовать его больше, вам нужно немало опыта для сравнения реализаций.После этого вы в идеале хотите сравнить реализации одного и того же.После этого вам необходимо тщательно знать о тестируемом и проверенном коде: если вы это сделаете, у вас будет лучшее понимание, чем оценка дерьма.

Чем выше, тем выше вероятность того, что его можно улучшить на несколькихтакие фронты, как тестируемость (включая эффективность) и точки изменения.Тем не менее, только когда результаты более 8000 или 9000, вероятность того, что что-то станет абсолютным CRAP, начнет приближаться к определенности.Что-то столь же простое, как обработка узлов из разобранного XML-документа для функции, которая не может быть решена каким-либо решительным образом, может легко привести к сотням сложностей, при этом оставаясь безупречной.

Это немного похоже на трату денег.Для определенной цели вам, возможно, придется потратить минимальную сумму.Это может быть миллион или тысяча, но независимо от цели мы склонны считать, что чем выше расходы, тем выше вероятность того, что они будут чрезмерными.Но, возможно, он должен быть высоким, возможно, вы покупаете яхту.Наивное сведение чисел не просто делает ту же ошибку в другом направлении, но действительно опасно.71 человек был сожжен до смерти или задыхался в башне Гренфелл из-за этой катастрофической ошибки в мышлении, полагая, что чего-то лучше всего достичь, если исходить только из одних чисел.

Не следует полагать, что уменьшение CRAP улучшает тестируемость илиремонтопригодность.Довольно часто высокий CRAP просто сообщает о степени обязательной сложности.Вы можете технически уменьшить CRAP, играя числа, одновременно уменьшая тестируемость, ремонтопригодность и удобочитаемость.Вы можете улучшить эти вещи, только улучшив их.CRAP даже не является надежной мерой улучшения.Иногда CRAP может выйти из строя после улучшения.Иногда это может пойти вверх.Проблема в метрических играх состоит в том, что люди часто просто смещают проблему или скрывают измеряемую вещь как показатель сложности.

Типичным примером является использование карты вместо переключателя или оператора if.Я склонен делать это самому религиозно.Однако мы забываем, что мы вытесняем сложность.В этом случае мы можем, у нас есть библиотека с утилитой карты, которая поддерживается и на которую можно положиться.Если вы включите эту функцию карты по сравнению с несколькими операторами if, общая мера сложности будет выше.Если в вашем распоряжении нет такой утилиты, вам нужно быть очень осторожным, как вы собираетесь уменьшить сложность.Например, если вы попытаетесь исключить операторы if и циклы for в целом, я желаю вам удачи в этом.

Цикломатическая сложность имеет тенденцию достаточно хорошо отражаться, если можно улучшить скорость испытаний.Это тривиально относится к таким случаям, как наличие двух операторов if в функции.Если состояние, на которое полагается второе, отличается в зависимости от того, совпадает первое или нет, то вы должны запустить первое избыточно (4 раза вместо 2).

Это также дает некоторое представление о том, сколько тестов вам действительно нужнос точки зрения параметров функции времени.Если у вас есть функция с одним логическим параметром и одним оператором if, основанным на ней, то вам нужно как минимум два теста, чтобы получить хотя бы полное покрытие кода.Два логических параметра и два оператора if, а затем четыре или три в зависимости от того, являются ли if вложенными.Количество комбинаций, которые вам, возможно, понадобится проверить, увеличивается на две степени только для каждой, если она добавляется после, если в худшем случае.

Это может создать конфликт, заставляющий вас преждевременно фрагментировать код, поскольку во время выполнения у вас может никогда не возникнуть такой проблемы.Как правило, вам не следует беспокоиться об этом до тех пор, пока тесты не начнут потреблять много ресурсов или фактически не станут непропорционально громоздкими.В этом случае вы бы не полагались на CRAP, но понимали бы выполнение кода и тесты.

CRAP может ошибиться, так как делает довольно наивное предположение о сложности.Вы приближаетесь к пессимистической или худшей оценке.Я смотрю на кусок кода, который имеет высокий CRAP, но он не может определить, имеет ли if($constantInScope)etc;etc;if($constantInScope)etc; или if($varA)etc;etc;if($varB)etc;.

Если одна функция действительно имеет сотни, тысячи или миллионы возможных результатовс точки зрения пути выполнения, это, вероятно, хороший признак того, что существуют проблемы с его тестированием.это может быть неизбежным.И наоборот, это может быть гораздо проще проверить, чем указано.Ограниченная способность измерять цикломатическую сложность может быть причиной того, что CRAP также включает в себя противовес покрытия.Если вы проверили его и получили большой охват, то, вероятно, его не так сложно протестировать, как думала цикломатическая сложность, особенно принимая во внимание, что можно сделать невозможным полное тестирование в терминах путей выполнения только по необходимости, хотяочень редко.

Простой пример того, почему CRAP бесполезен, разверните ваши циклы и замените операторы if математическими утверждениями и т.п., чтобы уменьшить CRAP.

...