gcovr / SonarQube говорят, что простая функция C ++ покрыта только наполовину

Мы запускаем gcovr на нашей кодовой базе, которая (FTR) затем загружается в SonarQube (cxx-plugin). Есть много мест, где отчет о покрытии менее 100%, даже если нет очевидных ответвлений, поэтому он обязательно должен быть 0 или 100%. Возьмем, к примеру, следующее:

std::string quote(const std::string& str, const std::string& quote_str) {
    return quote_str + str + quote_str;
}

В SonarQube первая строка отображается как «Полностью покрыта». Вторая строка отображается как Частично охвачена тестами (1 из 2 условий). Третья строка не упоминается - как и ожидалось. Вопрос в том, какие условия (я полагаю) gcovr видит на обратной линии, чего я не могу.

Я пробовал предложение от Почему gcc 4.1 + gcov сообщает о 100% охвате веток, а более новые (4.4, 4.6, 4.8) сообщают о 50% для p = новый класс; line? (добавление --exclude-throw-branch) и даже пробовали добавить --exclude-unreachable-branch. Кажется, без разницы.

Глядя на сгенерированный вывод xml, я замечаю, что обе первые несколько строк показывают 57 совпадений с branch = false. Мне интересно, откуда взялось условие 1 из 2, и, возможно, это SonarQube?

Кто-нибудь еще видел это или есть решение?

Обновить

Я не упоминал об этом с самого начала, потому что это не казалось актуальным, но мы используем clang v11 (не gcc) и, следовательно, llvm-cov gcov (а не сам gcov) ниже gcovr. Как показано ниже, это кажется важным.


person johnfo    schedule 23.09.2020    source источник
comment
Вполне возможно, что проблема в моей системе сборки. Вышеупомянутый анализ вывода XML-файла был выполнен локально, и без двух параметров исключения действительно XML-файл сообщает об условии (перехода). Если я перехватываю файл из системы сборки и смотрю на него, я вижу версию с условием перехода. Есть подозрение, что эти два параметра не применяются в системе сборки.   -  person johnfo    schedule 23.09.2020
comment
Я просмотрел сгенерированную сборку и немного поигрался с параметрами gcovr. Для меня --exclude-throw-branches действительно удаляет лишнюю ветку из отчетов. (Недостижимые ветки здесь не действуют, потому что этот параметр просто удаляет данные из строк, которые не похожи на код.) Сборка показывает больше ветвей, но это из-за встраивания, которое метод сбора покрытия игнорирует. Это не артефакт Sonarqube. Ваши подозрения в отношении системы сборки весьма вероятны. Для экспериментов с данными, которые видит gcovr, вы можете предпочесть запуск gcov напрямую.   -  person amon    schedule 24.09.2020


Ответы (2)


Я написал ранее комментарий, что это, возможно, sonarqube, но я посмотрел еще раз :) Я думаю, что ваши комментарии о возможных значениях ошибочны, потому что это стандартные строки C ++ (не C), поэтому эффективно не могут быть NULL как таковые . Однако есть возможное исключение OOM в добавлении - вы, вероятно, правы, что несопровождаемая ветвь является этим исключением.

Я провел несколько экспериментов, сравнивая вывод gcovr с использованием --exclude-throw-branch и --exclude-unreachable-branch. По сути, это не повлияло на отчет gcovr для этой строки, хотя это действительно имело значение для других строк.

Я не уверен, что упоминал, что мы используем clang, а не (скажем) gcc. Думаю, это может иметь значение. Не уверен. Каким бы ни было отражение, кажется, что это проблема gcov / gcovr, а не sonarqube. Первоначально я предполагал, что это не имело значения. Кажется, это так. Насколько я могу понять, llvm-com gcov (подкоманда llvm-cov, которая имитирует gcov) не генерирует теги, чтобы показать, что некоторые ветви отражают выбросы. Я посмотрел результат локально - мне, наверное, нужно сравнить с gcc и gcov. Однако это, кажется, настоящая проблема.

person johnfo    schedule 11.11.2020

может это SonarQube?

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

где 1 из 2 условий происходит от

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

+---------------------+
|   str   | quote_str |
+---------------------+
|   NULL  |   NULL    |
|   NULL  |  string   |
|  string |   NULL    |
|  string |  string   |
+---------------------+

Как видите, могут возникать некоторые исключения. Я считаю, что вы проверили только happy path, где не генерируются исключения, поэтому это причина, по которой охвачено только 1 of 2 conditions.

Как вы упомянули в комментарии, можно отключить условия, связанные с исключениями, добавив --exclude-throw-branches. У меня нет большого опыта работы с кодом C ++ (я разработчик Java), но я бы предпочел иметь меньшее покрытие кода и знать о потенциальных исключениях вместо того, чтобы видеть 100% покрытие и сталкиваться с неожиданными проблемами во время выполнения.

person agabrys    schedule 24.09.2020