Как использовать:
# Компиляция с флагами покрытия
g++ -fprofile-arcs -ftest-coverage -O0 -g myapp.cpp -o myapp
# Запуск тестов
./myapp_tests
# Генерация отчетов
gcov myapp.cpp
lcov --capture --directory . --output-file coverage.info
genhtml coverage.info --output-directory coverage_report
Плюсы:
Как использовать:
clang++ -fprofile-instr-generate -fcoverage-mapping test.cpp -o test
./test
llvm-profdata merge -sparse default.profraw -o default.profdata
llvm-cov show ./test -instr-profile=default.profdata
Преимущества:
Включение:
Configuration Properties > Code Coverage > Enable Code Coverage
Аргументы ЗА:
Аргументы ПРОТИВ:
// Плохо: тест ради покрытия
TEST(MyTest, UselessTest) {
MyClass obj;
obj.method(); // Проверок нет, но покрытие растет
}
// Хорошо: осмысленный тест
TEST(MyTest, MeaningfulTest) {
MyClass obj;
auto result = obj.method();
ASSERT_EQ(expected, result); // И покрытие, и проверка логики
}
Пример для GitLab CI:
test_with_coverage:
script:
- g++ --coverage -O0 -g tests.cpp -o tests
- ./tests
- gcovr --exclude-unreachable-branches --xml-pretty -o coverage.xml
- gcovr --exclude-unreachable-branches --print-summary
artifacts:
reports:
cobertura: coverage.xml
Инструменты вроде Mull проверяют, могут ли тесты обнаружить искусственно внесенные ошибки
Clang-Tidy, Cppcheck могут находить непроверенные edge cases
Библиотеки вроде RapidCheck проверяют инварианты для случайных входных данных
Измерение покрытия тестами:
Как делать?
Нужно ли?
Как интерпретировать?
Золотое правило: "Покрытие тестами показывает, что код работает, а не что он работает правильно". Используйте метрики покрытия как один из многих инструментов контроля качества.