Introduction: Why "Green" Tests Are Not Yet a Victory?
\n\nImagine: you run a thousand unit-tests, they all pass with a green checkmark, the CI pipeline is happy, the manager is pleased. But a week passes, and a critical bug crashes in production. Sound familiar? Most often, the problem is that tests exist, but they do not check the actually executed code. They might test only 10% of the source code, while the remaining 90% is a "gray zone" where bugs hide.
\n\nThis is where code coverage testing in C++ (code coverage) comes into play. It's not just a trendy metric for reporting to the client. It's your X-ray machine that shows: which lines of code are actually executed during tests, and which have never been run. Today, we'll break down how to properly configure coverage tools for C++, which metrics truly matter, and how not to drown in false positives.
\n\nWhat is Code Coverage and Why Does a C++ Developer Need It?
\n\nCode coverage is a metric that shows what percentage of your program's source code was executed during test runs. In C++, this is especially critical because the language allows writing low-level code, optimizations, and template magic that can "backfire" at the most unexpected moment.
\n\nMain Types of Coverage Metrics
\nNot all metrics are equally useful. Here's what really matters:
\n- \n
- Line Coverage — the most basic metric. How many lines of source code were touched. Easy to measure, but easy to fool. \n
- Branch Coverage — checks whether both branches of each
if/elseorswitchwere traversed. Much more honest than line coverage. \n - Function Coverage — was the function called at least once. Useful for finding "dead" code. \n
- Condition Coverage — checks all sub-expressions in complex logical operators (
&&,||). The strictest, but also the most resource-intensive. \n
For a typical C++ project, good practice is considered a target of 70-80% line coverage and at least 60% branch coverage. 100% coverage is a utopia, but striving for 90% in critical modules (memory management, network protocols) is a very realistic task.
\n\nTools for Analyzing C++ Code Coverage
\n\nThe C++ ecosystem offers several powerful tools. We'll look at the top 3 that are actually used in production.
\n\n1. Gcov — The Classic from GCC
\ngcov is a built-in tool in the GCC compiler. It works at the machine code level, so it gives very accurate results. Main advantages: free, open source, works with CMake and Makefile.
How to run:
\n// Compile with coverage flags\ng++ -fprofile-arcs -ftest-coverage -O0 main.cpp -o test_app\n\n// Run tests\n./test_app\n\n// Generate report\ngcov main.cpp\nAfter this, you will get *.gcov files showing how many times each line was executed. Downside: the output format is textual, not very visual.
2. LCOV — Graphical Interface for Gcov
\nlcov is an overlay on gcov that generates beautiful HTML reports. You can see green (covered) and red (uncovered) lines directly in the browser.
# Collect coverage data\nlcov --capture --directory . --output-file coverage.info\n\n# Generate HTML\ngenhtml coverage.info --output-directory coverage_report\nThis is the industry standard for CI/CD. Jenkins, GitLab CI, GitHub Actions — everywhere you can configure automatic LCOV generation.
\n\n3. Clang Sanitizer Coverage (Source-based)
\nIf you use Clang, you have access to -fsanitize-coverage. E