Перейти к содержанию

Оценки здоровья

Qualimetrix вычисляет 6 оценок здоровья для каждого класса, пространства имён и проекта — от 0 (худшее) до 100 (лучшее). Оценки здоровья сводят десятки метрик в быструю картину качества, позволяя моментально определить, какие участки кодовой базы требуют внимания.


Измерения

Измерение Что измеряет Ключевые метрики Пороги (warning / error)
health.complexity Сложность методов и классов CCN (avg, max, p95), Cognitive Complexity 50 / 25
health.cohesion Связность методов внутри класса TCC, LCOM4, количество методов 50 / 25
health.coupling Зависимости между классами и пространствами имён CBO, Distance from Main Sequence, efferent coupling 50 / 25
health.typing Покрытие типами Типы параметров, возвращаемых значений, свойств 80 / 50
health.maintainability Лёгкость безопасной модификации Maintainability Index (avg, p5, min) 50 / 25
health.overall Взвешенное среднее всех измерений Все вышеперечисленные 50 / 30

Уровни оценки

Каждой оценке присваивается текстовый уровень на основе значения относительно порогов warning (W) и error (E):

  • Excellent: score > W + (100 − W) × 0.6
  • Good: score > W + (100 − W) × 0.3
  • Fair: score > W
  • Poor: score > E
  • Critical: score ≤ E

Для стандартных измерений (W=50, E=25):

Уровень Диапазон
Excellent > 80
Good 65 – 80
Fair 50 – 65
Poor 25 – 50
Critical ≤ 25

Пороги health.typing отличаются

У health.typing пороги по умолчанию W=80, E=50, поэтому границы уровней сдвинуты: Excellent > 92, Good > 86, Fair > 80, Poor > 50, Critical ≤ 50.


Как работают оценки

Все оценки здоровья используют штрафной подход: оценка начинается со 100 и уменьшается при обнаружении проблем. Результат ограничивается диапазоном 0–100 функцией clamp. Такой подход обеспечивает хорошую дифференциацию — проекты с умеренными проблемами не скатываются сразу в ноль, а различия между «хорошим» и «отличным» кодом остаются видны.

health.complexity

Штрафует за высокую цикломатическую и когнитивную сложность. На уровне класса учитывается средняя и максимальная сложность методов. На уровне пространства имён дополнительно анализируется p95 (95-й перцентиль), что позволяет обнаруживать выбросы — отдельные аномально сложные методы. Максимальная сложность масштабируется через квадратный корень, чтобы один метод-монстр не обрушивал оценку всего пространства имён.

Методы интерфейсов включены в агрегацию

Методы интерфейсов имеют минимальную сложность (CCN=1, cognitive=0, NPath=1) и включены в расчёт .avg и .p95 на уровне пространства имён. В проектах с большим количеством интерфейсов средняя сложность может оказаться ниже ожидаемой. Это сделано намеренно — интерфейсы являются частью кодовой базы — но добавление интерфейсов может немного улучшить оценку сложности без реальных изменений логики.

health.cohesion

Оценивает, насколько методы класса работают с общими данными. Основана на TCC (Tight Class Cohesion) и LCOM4. Формула корректирует «чистые» методы (без обращения к свойствам) — такие методы завышают LCOM и занижают TCC, не являясь реальной проблемой. Для классов с менее чем 6 методами применяется смягчённая оценка.

health.coupling

Измеряет зависимости на уровне класса и пространства имён. На уровне класса используется гиперболическое затухание: зависимости за пределами порога снижают оценку, но каждая следующая зависимость влияет слабее предыдущей. На уровне пространства имён дополнительно учитываются Distance from Main Sequence, средний и экстремальный CBO.

health.typing

Непосредственно отражает процент покрытия типами (Type Coverage): параметры, возвращаемые значения и свойства. На уровне пространства имён агрегирует суммы по всем классам.

health.maintainability

Основана на Maintainability Index. На уровне класса штрафует за низкий средний MI и за отдельные методы с экстремально низким MI (масштабирование через квадратный корень). На уровне пространства имён основные дифференциаторы — p5 (5-й перцентиль) и минимальное значение.

health.overall

Взвешенное среднее всех измерений. Веса различаются по уровням:

  • Класс: complexity 35%, cohesion 25%, coupling 25%, typing 15% (maintainability исключена — MI является метрикой уровня метода и её сигнал уже учтён через complexity и cohesion)
  • Пространство имён / проект: complexity 30%, cohesion 20%, coupling 20%, typing 10%, maintainability 20%

Чтение оценок здоровья

Оценки здоровья доступны в трёх форматах вывода:

summary (по умолчанию) — прогресс-бары в терминале:

Qualimetrix — 45 files analyzed, 1.23s

  Complexity     ████████████████░░░░  78 Excellent
  Cohesion       ██████████████░░░░░░  68 Good
  Coupling       ████████████░░░░░░░░  59 Fair
  Typing         ██████████████████░░  88 Excellent
  Maintainability████████████████░░░░  80 Good
  Overall        ██████████████░░░░░░  72 Good

json — структурированные данные для CI/CD:

bin/qmx check src/ --format=json

health — текстовая таблица оценок здоровья в терминале:

bin/qmx check src/ --format=health

html — интерактивный отчёт с drill-down по пространствам имён и классам:

bin/qmx check src/ --format=html -o report.html

Подробнее о форматах вывода — в разделе Форматы вывода.


Настройка

Настройка порогов

Переопределите пороги warning/error для любого измерения здоровья:

computed_metrics:
  health.complexity:
    warning: 60
    error: 30
  health.typing:
    warning: 90
    error: 70

Отключение измерения

computed_metrics:
  health.typing:
    enabled: false

Или только скрыть из отображения (оценки по-прежнему вычисляются):

bin/qmx check src/ --exclude-health=typing

Переопределение формул

Переопределите формулу для одного или нескольких уровней:

computed_metrics:
  health.complexity:
    formulas:
      class: 'clamp(100 - max((ccn__avg ?? 1) - 5, 0) * 3.0, 0, 100)'

Используйте formula (единственное число), чтобы задать одну формулу для всех уровней:

computed_metrics:
  health.complexity:
    formula: 'clamp(100 - max((ccn__avg ?? 1) - 5, 0) * 3.0, 0, 100)'

Пользовательские вычисляемые метрики

Создавайте собственные метрики с произвольными формулами. Пользовательские метрики используют префикс computed.:

computed_metrics:
  computed.my_score:
    description: "Custom quality score"
    formula: 'clamp((health__complexity ?? 75) * 0.5 + (health__coupling ?? 75) * 0.5, 0, 100)'
    levels: [class, namespace, project]
    inverted: true
    warning: 60
    error: 30

Всегда используйте оператор ??

Метрики могут отсутствовать для некоторых символов (например, у интерфейсов нет тела методов). Оператор ?? задаёт значение по умолчанию и предотвращает ошибки вычисления: (ccn__avg ?? 1).

Доступные переменные

В формулах доступны все метрики символа. Точки в именах метрик заменяются на __:

Переменная Описание Доступна на уровне
ccn__avg, ccn__max Средняя и максимальная цикломатическая сложность class, namespace, project
ccn__sum, ccn__p95 Сумма и 95-й перцентиль CCN namespace, project
cognitive__avg, cognitive__max Средняя и максимальная когнитивная сложность class, namespace, project
cognitive__sum, cognitive__p95 Сумма и 95-й перцентиль Cognitive namespace, project
tcc / tcc__avg Tight Class Cohesion (0–1) class / namespace, project
lcom / lcom__avg LCOM4 class / namespace, project
cbo__avg, cbo__max, cbo__p95 Агрегаты Coupling Between Objects namespace, project
ce, ce_packages Efferent coupling (зависимости, количество пакетов) class
distance / distance__avg Distance from Main Sequence namespace / project
mi__avg, mi__min Средний и минимальный Maintainability Index class, namespace, project
mi__p5 5-й перцентиль MI namespace, project
typeCoverage__pct Процент покрытия типами class
methodCount Количество методов в классе class
symbolMethodCount Количество методов в области видимости символа namespace, project
pureMethodCount_cohesion «Чистые» методы (без обращения к свойствам) class
health__complexity, health__cohesion, ... Значения других оценок здоровья class, namespace, project

Это не исчерпывающий список — в формулах можно использовать любую метрику, собираемую Qualimetrix. Команда bin/qmx check src/ --format=metrics-json покажет все доступные метрики для вашего проекта.

Неизвестные ссылки на метрики

Если формула ссылается на несуществующую метрику (например, опечатка ccn__abg вместо ccn__avg), Qualimetrix выдаст явную ошибку вместо молчаливого возврата нуля. Всегда используйте оператор ?? для метрик, которые могут обоснованно отсутствовать: (ccn__avg ?? 0).

Доступные функции

Функция Описание
min(a, b) Минимум из двух значений
max(a, b) Максимум из двух значений
abs(x) Модуль числа
sqrt(x) Квадратный корень
log(x) Натуральный логарифм
log10(x) Десятичный логарифм
clamp(value, min, max) Ограничение значения диапазоном [min, max]

Также поддерживаются стандартные операторы Symfony Expression Language: +, -, *, /, ** (возведение в степень), ?? (null coalescing), тернарный оператор.