SonarQube и непокрытые фигурные скобки

2023.05.03
Разбираемся в SonarQube, его устройстве и вообще как так может быть что фигурные скобки не покрываются тестами?

Попалась мне задача по работе: разобраться почему SonarQube показывает некоторые фигурные скобки как непокрытые тестами.

Непокрытые тестами фигурные скобки

Какая-то глупость, как фигурная скобка может быть непокрыта тестами? Она же не исполняется. Ну ладно, у разработчиков есть проблема, надо решить.

Получив вводные данные я был направлен по ложному пути этого issue на github, обсуждение за 2015 год, в 2023 мысль о понижении версии мне не внушала доверия, но я попробовал - не помогло. Однако я слегка забегаю вперед ...

Как SonarQube определяет покрытие кода?

Задача странная для незнакомого с устройством SonarQube.

Немного погуглив можно узнать что проблема может быть в не соответствии стандартам, а здесь и тут несведомые получают откровение, подтверждаемое документацией:

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

Логично, как я раньше не мог догадаться что SonarQube это интерфейс для сторонних отчетов :)

Для формирования отчетов покрытия кода на PHP используем PHPUnit, в документации по анализу покрытия кода есть теорические вводные, а в xml конфиге можно указать report с соответсвующими форматами, например clover (быстрый поиск нашел только openclover).

Пример clover отчета:

<?xml version="1.0" encoding="UTF-8"?>
<coverage generated="1683228154">
    <project timestamp="1683228154">
        <package name="MyPackege">
            <file name="/full/path/to/file.php">
                <class name="MyClass" namespace="MyNamespace">
                    <metrics
                        complexity="67"
                        methods="41"
                        coveredmethods="38"
                        conditionals="0"
                        coveredconditionals="0"
                        statements="130"
                        coveredstatements="127"
                        elements="171"
                        coveredelements="165"
                    />
                </class>
                <!--общая информация о покрытии метода-->
                <line
                    num="86"
                    type="method"
                    name="myMethod"
                    visibility="public"
                    complexity="2"
                    crap="2"
                    count="240"
                />
                <!--
                    информация о покрытии конкретной строки,
                    count == количество тестов покрывающих эту строку
                -->
                <line num="99" type="stmt" count="240"/>
                ...
            </file>
            ...
        </package>
        ...
    </project>
    ...
</coverage>

В clover файле есть информация о каждой строке кода (не считая комментариев), которая может покрываться тестами (count>0) или не покрываться (count==0).

Теперь нам нужен sonar-project.properties, где необходимо указать данные проекта и путь до clover отчета.

А теперь, можно отправлять в SonarQube:

$ sonar-scanner -Dproject.settings=sonar-project.properties

И все-таки: почему скобки не покрыты тестами?

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

Оба этих отчета отправлялись в SonarQube. И это было ошибкой.

Если метод/функция хоть как-то покрывается тестами, то в отчете не будет информации о фигурных скобках, но если метод/функция не покрыт тестами, то в отчет попадет информация о непокрытых тестах.

Посмотрим как выглядит полностью покрытый тестами метод:

А вот так выглядит вообще не покрытый метод:

Объединив оба вида теста в один проход, получили один clover отчет. Загрузили в SonarQube - непокрытые тестами скобки исчезли.

Итог

Вот так незамысловато был получен баг, а впоследствии разобран. Заодно я познакомился с SonarQube и его устройством.

В телеграм канале DevOps от первого лица можно оставить комментарий или почитать интересные истории из практики DevOps