Покрытие кода (code coverage)
Покрытие кода – метрика ПО, показывающая процент исходного кода программы, который был выполнен в процессе тестирования.
Платформы тестирования С/C++ кода:
Платформа модульного тестирования Майкрософт для C++ (VS)
[Catch2, [in CLion](https://www.jetbrains.com/help/clion/catch-tests-support.html]](https://github.com/catchorg/Catch2)
OpenCppCoverage (C++, Windows)
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

Last updated