Статьи

Метрики кода и вы

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

Теперь, когда мы установили некоторые преимущества метрик кода, давайте поговорим о некоторых подводных камнях. К сожалению, как и многие другие вещи в мире разработки программного обеспечения, метрики кода не являются единственным решением. Измерение производительности по любой метрике кода приведет к тому, что программисты закодируют метрику. Например, если эта метрика — покрытие тестами, они напишут один тест, который запускает утверждение для каждого файла. Это может быть не так вопиюще, но если вы структурируете какие-либо стимулы вокруг этих показателей, они будут задействованы.

Другая распространенная ловушка — предположить, что эти метрики действительно что-то значат. Метрики могут дать вам понимание, но для того, чтобы это понимание было действенным, вам нужно предпринять продуманные шаги, чтобы убедиться, что проблема действительно существует. Как только вы решили, что есть проблема, вам нужно посмотреть, стоит ли ее устранять. И последнее, это никогда не огонь и не забудьте инструменты. Они требуют размышления, времени и усилий, чтобы быть полезными.

В этой статье я расскажу о трех наиболее распространенных метриках кода. Сначала поговорим о цикломатической сложности, а затем о метрике ABC, а затем перейдем к тестированию покрытия. Для каждого из них я объясню, что это такое, настолько подробно, насколько позволяет этот формат, и расскажу об инструментах, которые вы можете немедленно использовать для тестирования собственного кода. Хорошо, здесь мы идем …

Цикломатическая Сложность

Цикломатическая сложность — это графическое измерение количества возможных путей через нормальный поток программы. [ 1 ] Например, программа без операторов ветвления имеет оценку один. Расчет цикломатической сложности метода осуществляется с помощью управляющего потокового графа. Эти графики состоят из узлов и ребер. Каждый узел в программе представляет собой базовый оператор, а каждое ребро представляет изменения в потоке управления программы. Это все очень сложно понять, поэтому давайте рассмотрим пример.

Учитывая этот кусок Ruby:

def cyclomatic_complexity_of_two(arg) if arg # Node A puts "Foo" # Node B else puts "Bar" # Node C end end # Node D 

Мы начнем строить наш график. Сначала нам нужно выяснить, сколько узлов, ребер и конечных точек у нас есть. У нас есть только одна конечная точка в конце метода. Наша строка if arg представляет узел, так же как наша puts "Foo" и puts "Bar" , а также нашу конечную точку. Наконец, наши края от:

  • От А до Б
  • От А до С
  • От B до D
  • С на D
  • И наша конечная точка возвращается к нашей точке входа (виртуальный край)

Мы заканчиваем четырьмя узлами, пятью ребрами и одной конечной точкой. После того, как мы сделали все это, мы находим цикломатическую сложность, беря Edges - Nodes + Endpoints [ 2 ] . Сюжет вышеописанного метода выглядит так:

Если вы хотите узнать больше о цикломатической сложности, прочитайте эту статью Артура Уотсона и Томаса МакКейба.

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

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

Начало работы с CC

Наша первая остановка на земле Руби — Сайкуро. Это программа, используемая для измерения цикломатической сложности вашей программы. Вы можете скачать его здесь , а затем запустить ruby setup.rb all . В качестве альтернативы вы можете установить: gem install atoulme-Saikuro , который является клоном основного хранилища Saikuro. Я считаю, что последнее немного удобнее (а не как в старой школе).

После этого вы можете запустить свой первый отчет Saikuro с помощью следующей команды. Поскольку он генерирует html (или текстовый) отчет, я рекомендую создать каталог для вывода и отправить его туда. В противном случае по умолчанию помещаются отчеты в текущий каталог.

 ~$ mkdir ./saikuro_output ~$ saikuro -c -o saikuro_output -p euclid_equation.rb ~$ open ./saikuro_output/index_cyclo.html 

Чтобы просмотреть параметры, запустите saikuro -h , saikuro -h выше команда сообщает Saikuro создать отчет о:

  • Цикломатическая сложность ( -c )
  • Выходной каталог ( -o )
  • И проанализировать ( -p ) этот файл.

Внутри html-файла вы увидите отчет, содержащий подробную информацию о проанализированном файле.

Saikuro измеряет сложность, но, как я уверен, вы знаете, Ruby — сложный язык. Saikuro добавляет ветку, когда встречает (если, если, пока, пока, для, elsif, когда), но также добавляет ветку, если код использует блок. Рационализация здесь заключается в том, что использование блока внутри вашего кода очень часто меняет поток управления.

Например, вызов «каждого» метода массива с блоком будет проходить только по данному блоку, если массив не пустой. [ 3 ]

Сайкуро также игнорирует операторы && и, and , хотя в идеальном мире это увеличит цикломатическую сложность.

Вы можете сделать так, чтобы он сообщал рекурсивно в директорию или предназначался для проблемного класса. Если вы хотите больше контролировать использование Saikuro, вы можете использовать версию SaikuroRunner.new.run(rb_files, output_dir) и: SaikuroRunner.new.run(rb_files, output_dir) .

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

ABC Метрика

К счастью, есть несколько статей [ 4 ] по метрике ABC, которые были найдены достаточно для того, чтобы на самом деле сделать это Google-способным. :: grumble :: В любом случае, метрика ABC — это еще один способ измерения сложности, хотя ее создатель громогласно заявляет, что это измерение размера программы, аналогичное LoC. В любом случае, это, безусловно, метод для лучшего понимания, где ваш код может иметь проблемы.

Метод ABC — это метод, с помощью которого баллы собираются для каждого компонента — назначение, ветвление и вызовы — затем рассчитываются в балл, который легко понять. Формула

и округляется до десятых. Счет сохраняется в векторном формате и выглядит как <a,b,c> до тех пор, пока вы не захотите получить итоговое значение, а затем рассчитывается в скалярном формате.

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

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

Давайте перейдем прямо к разделу «Начало работы», потому что мы используем Flog.

Начало работы с ABC

Итак, инструмент, о котором мы собираемся поговорить, это Флог. Это инструмент, который широко используется в течение длительного времени, поэтому, по всей вероятности, вы слышали о нем или даже потенциально использовали его. Поэтому я не буду тратить слишком много времени на установку, просто gem install flog и вы отправитесь в гонки.

Первое, что нужно знать о Флоге, это то, что он самоуверенный. Очень самоуверенный. Скоринг построен специально для применения общепринятых шаблонов проектирования для Ruby. Таким образом, мы должны думать о Flog как об использовании измененной метрики ABC. Например, использование инъекций с юмором (если немного хитро) приносит вам два очка .

Термины ветвления :and, :case, :else, :if, :or, :rescue, :until, :when, :while ,: :and, :case, :else, :if, :or, :rescue, :until, :when, :while ,: before,: :and, :case, :else, :if, :or, :rescue, :until, :when, :while . Существуют и другие правила, которые добавляют к общему количеству веток, но это хорошее начало. Задание довольно простое, добавьте одно к баллу за назначение. Вызовы — это любой вызов метода, который выводит поток из текущей области.

В своем выступлении [ 5 ] Джейк Скраггс (автор metric_fu) в 2008 году аккуратно суммировал эмпирическое правило, которое мне нравится помнить при использовании Flog:

  1. 0-10 — Отлично. Но это что-нибудь делает?
  2. 11-21 — Хорошо.
  3. 21-40 — Возможно, потребуется рефакторинг.
  4. 41-60 — Вы могли бы оправдать код. (т.е. стоимость рефактора препятствует действию)
  5. 61-? — Опасно, расследуйте, когда это возможно.

Хорошо, с этим давайте использовать это. Учитывая следующее Ruby:

 # euclids_equation.rb def gcd(x, y) while y != 0 r = x % y x = y y = r end x end 

Мы можем запустить Flog для этого кода с помощью flog ./euclids_equation.rb . И мы получаем вывод:

Как видите, этот метод получает 4.4. Сводка по умолчанию также показывает среднее значение метода; если бы было больше методов, это отражало бы среднюю сложность каждого метода. У Flog есть много опций, включая поддержку синтаксического анализа для синтаксиса 1.8 и 1.9. Как вы можете видеть, код выполняется довольно быстро, что делает его идеальным для хитрости.

Хук предварительной фиксации, который проверяет сложность кода и возвращает ненулевое значение для любого значения выше 61, работает довольно хорошо. А так как вы всегда можете обойтись с помощью --no-verify , это не помешает вам нормально работать, если вы не хотите беспокоиться.

Теперь, когда вы познакомились с Flog, давайте поговорим об освещении.

Покрытие кода

Покрытие кода является мерой, используемой при тестировании программного обеспечения. Он описывает степень, в которой исходный код программы был проверен. [ 6 ]

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

  • C1 покрытие — это базовое покрытие заявления (также то, что использует simplecov). Одно из самых основных измерений. Просто измеряет, что каждый оператор выполняется (или, по крайней мере, загружается) через тесты.
  • Покрытие C2 — это покрытие филиала. Измеряет, что есть тест для каждого края потока.

Есть ряд других типов измерений покрытия, которые полезны. Если вам интересно, я бы рекомендовал прочитать эту статью о различных видах освещения. Мы в первую очередь сосредоточимся на C1 и C2 с simplecov , так что я не буду более simplecov на этом. Но знайте, что существует много способов определения покрытия тестами.

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

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

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

Начало работы с покрытием

Как кратко упоминалось ранее, мы будем использовать simplecov . Simplecov — это гем, который может быть легко интегрирован в приложение Rails или другой проект Ruby, и предоставляет небольшую хитрую HTML-страницу, которая показывает ваше тестовое покрытие.

Установка немного более интенсивна, чем предыдущие инструменты, перечисленные здесь, но все же довольно проста. Добавьте следующую строку в ваш test / spec_helper и запустите ваши тесты.

 require 'simplecov' SimpleCov.start 

Затем откройте coverage/index.html и вы увидите что-то похожее на это:


Изображение со страницы GitHub SimpleCOV. [ 7 ]

Чтобы увидеть выделенную версию, где красным цветом показаны не выполненные строки, вы можете щелкнуть пути к файлам. И это в основном так.

C1 (покрытие заявления) — это то, о чем сообщает simplecov, и хотя вы не можете использовать эту информацию, чтобы точно определить, насколько здорова ваша программа, вы можете использовать этот обзор, чтобы дать вам возможность начать. Это особенно полезно для устаревших приложений, где вы еще не знаете точно, где находятся проблемные области.

Давайте подведем итоги

Мы смотрели на это:

  1. Цикломатическая сложность — это графическое измерение количества возможных путей через нормальный поток программы.
    • Сайкуро — анализирует цикломатическую сложность и пишет хороший отчет для оценки.
  2. ABC метрика — метод, с помощью которого собираются оценки для каждого компонента-назначения, ветвления и вызовов, а затем рассчитываются в оценку, которая может быть легко понята.
    • Flog — Надежный и надежный инструмент командной строки, который запускает ABC метрику.
  3. Покрытие кода — мера, используемая в тестировании программного обеспечения и используемая для описания степени тестирования исходного кода программы.
    • Simplecov — отличный инструмент для создания отчетов о тестировании, который легко интегрируется в Rails и другие проекты Ruby.

С чего начать

Все инструменты, рассмотренные выше, являются хорошим способом начать. Если бы я начал использовать метрики кода сегодня, я бы начал с Флога. Существуют хорошие ресурсы с информацией о том, как начать работу с ней, и я считаю, что ее самоуверенный характер поможет вам начать задавать вопросы, о которых вы могли бы и не подумать иначе. Начните с использования измерения, которое придумал Джейк Скраггс (см. Выше), и по-настоящему задумайтесь над тем, откуда эта сложность. Как только вы почувствуете, как Flog идентифицирует слишком сложный код, переходите к другим инструментам и начинайте понимать, как они связаны.

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

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

Ссылки

Отдельное спасибо @telemachus и @pat_shaugnessy за помощь в редактировании.

  1. Пересмотр цикломатической сложности (infoq) , Гэвин Террилл, 2008
  2. «Структурное тестирование: методология тестирования с использованием метрики цикломатической сложности» , Артур Уотсон, Томас МакКейб, 1996
  3. Сайт Сайкуро , Зев Блут, 2005
  4. Применение метрики ABC к C, C ++ и Java , Джерри Фицпатрик, 1997
  5. Использование метрик, чтобы взглянуть на ваш код , Джейк Скраггс, 2008
  6. Википедия Покрытие кода
  7. Simplecov