c-cpp-cookies
  • Полезные материалы
    • About
  • Настройка окружения
    • Git
      • Git CLI
      • Git GUI
      • Git Web
      • Git в среде разработке
        • Visual Studio
        • Visual Studio Code
        • CLion
        • Qt Creator
    • Стандарты (они же ISO)
    • Qt about
    • IDE
      • Visual Studio Code
        • Код в Visual Studio Code
        • Разработка в Visual Studio Code
      • Visual Studio
        • Настройки Visual Studio и проектов
        • Код в Visual Studio
        • Visual Studio + GitHub
      • Qt + Qt Creator
        • Установка Qt и QtCreator
        • Примеры проектов на Qt
      • CLion
        • Настройки CLion
        • Код в CLion
        • CLion + GitHub
    • Компиляторы
      • Clang + Visual Studio
      • Clang + CLion
  • Best practices
    • Антипаттерны и способы улучшения кода
      • 0. Освобождение ресурсов
      • 1. Чтение данных из файла
      • 2. Открытие файлов
      • 3. Объявление переменных
      • 4. Выделение памяти
      • 5. Необдуманный код
      • 6. Глубокие if
      • 7. Длинные if
      • 9. Non-void функции
      • 10. Создание массивов
      • 11. Проверка формата файла
  • Сборка программы
    • Сборка программы
    • Системы сборки / Build systems
      • Проект и решение
      • Make
      • Ninja
      • CMake
      • MSBuild
    • Подключение внешних библиотек
    • Библиотеки
  • Отладка
    • Отладка / Debugging
    • Запуск программы
    • Точки останова / Breakpoints
      • Обычные точки останова / General breakpoint
      • Условные точки останова / Conditional breakpoint
      • Зависимые точки останова / Dependent breakpoint
      • Временные точки останова / Temporary breakpoint
      • Точки трассировки / Breakpoint actions и tracepoints
    • Стек вызовов / Call stack
    • Локальные переменные / Locals
    • Просмотр области памяти / Memory view
    • Исключения / Exceptions
  • Анализ
    • Поиск утечек памяти
    • Санитайзеры
  • Возможности IDE
    • Возможности IDE
    • Продвинутый текстовый редактор
    • Закладки / Bookmarks
    • Платформы / Platforms
    • Конфигурации сборки / Build configurations
    • Шаблонные проекты / Project templates
    • Терминал / Terminal
    • Сборка / Build
    • Запуск программы / Run program
    • Code style
    • Работа с Github Actions
  • Тестирование
    • Тестирование
    • Google test
      • Gtest в VS
      • Gtest в CLion
      • Gtest в VSCode
    • Покрытие кода (code coverage)
Powered by GitBook
On this page
  • Code coverage с llvm-cov
  • Code coverage с gcov
  • Code coverage в Visual Studio
  • Code coverage в CLion
  1. Тестирование

Покрытие кода (code coverage)

PreviousGtest в VSCode

Last updated 1 month ago

Покрытие кода – метрика ПО, показывающая процент исходного кода программы, который был выполнен в процессе тестирования.

Платформы тестирования С/C++ кода:

[Catch2, [in CLion](https://www.jetbrains.com/help/clion/catch-tests-support.html]](https://github.com/catchorg/Catch2)

Code coverage с llvm-cov

Устанавливается вместе с LLVM.

Рассмотрим пример:

include/max.hpp

#pragma once

template<typename T>
T max(const T &a, const T &b)
{
	return (a >= b ? a : b);
}

struct Pixel
{
    char r, g, b;
};


#define Y(p) (0.299*(p.r) + 0.587*(p.g) + 0.114*(p.b))

template<>
Pixel max<Pixel>(const Pixel &a, const Pixel &b)
{  
	return (Y(a) > Y(b)) ? a : b;
}

tests.cpp

#include <gtest/gtest.h>

#include "max.hpp"

TEST(Max, Int) {
    EXPECT_EQ(max<int>(5, 3), 5);
}

TEST(Max, IntImplicit) {
    EXPECT_EQ(max(5, 3), 5);
}

TEST(Max, Float) {
    EXPECT_EQ(max<float>(5, 3), 5.0f);
}

int main(int argc, char **argv)
{
	::testing::InitGoogleTest(&argc, argv);
	return RUN_ALL_TESTS();
}

Для того, чтобы покрытие кода можно было измерить, необходимо собрать программу с опциями -fprofile-instr-generate -fcoverage-mapping. Эти опции говорят компилятору о необходимости вставки дополнительных инструкций для сбора статистики.

В нашем случае (сборка из корня проекта):

clang -fprofile-instr-generate -fcoverage-mapping -O0 -Iinclude .\test\tests.cpp -Iinclude -Igtest\include -Lgtest\lib\ -lgtest -o tests.exe

Если запустить собранный файл:

.\tests.exe

то в результате запуска будет сгенерирован файл default.profraw – файл, содержащий данные профайлинга.

Если проект содержит несколько main-функций (main.cpp и tests.cpp), то можно сгенерировать разные profraw и затем объединить в единый отчёт:

llvm-profdata merge -sparse tests.profraw main.profraw -o tests.profdata                                   

profdata – промежуточный файл llvm-cov, используемый для генерации отчёта.

Для генерации отчёта можно использовать

llvm-cov show .\tests.exe -instr-profile tests.profdata -format html -output-dir coverage_report -ignore-filename-regex=".*[/\]gtest[/\].*" 

В результате исполнения данной команды будет создана директория coverage_report, в которой появится отчёт в формате HTML, в который не будут включены результаты, содержащие подстроку gtest (исключаем все логи про покрытие тестами самого gtest).

В случае приведённого выше кода статистика будет следующей:

Code coverage с gcov

Аналог: gcovr.

Установка: pip install gcovr

Идея аналогична llvm-cov – генерируются файлы профайлинга, а затем из них формируется отчёт.

Вариант описания CMakeLists.txt для автоматической сборки и формирования отчёта о покрытии кода:

cmake_minimum_required(VERSION 3.14)
project(example)

set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fprofile-arcs -ftest-coverage")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS}     -fprofile-arcs -ftest-coverage")

# Specify the C++ standard
set(CMAKE_CXX_STANDARD 23)
set(CMAKE_CXX_STANDARD_REQUIRED True)

add_subdirectory(lib)

include(FetchContent)
FetchContent_Declare(
  googletest
  URL https://github.com/google/googletest/archive/03597a01ee50ed33e9dfd640b249b4be3799d395.zip
)

set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
FetchContent_MakeAvailable(googletest)

enable_testing()

add_executable(mainTest test/tests.cpp)

add_custom_target(cov 
COMMAND echo "=================== GCOVR ====================" 
COMMAND gcovr -r ${CMAKE_SOURCE_DIR} --exclude='${CMAKE_SOURCE_DIR}/build' --exclude='${CMAKE_SOURCE_DIR}/Eigen'
COMMAND open coverage.html)

add_dependencies(cov mainTest)

target_link_libraries(mainTest gtest gtest_main)

add_test(NAME mainTest COMMAND mainTest)

Code coverage в Visual Studio

Code coverage в CLion

Подробнее .

изображение

Пример использования .

изображение
изображение
Платформа модульного тестирования Майкрософт для C++ (VS)
Google Test
Boost.Test
CTest (CMake)
OpenCppCoverage (C++, Windows)
gcov(CLI) / lcov (GUI) (GCC)
llvm-cov (LLVM/Clang, CLI)
здесь
здесь