This guide explains how to run code coverage analysis on the IPv6-parse library.
./build_and_test_coverage.shThis will:
- Clean previous coverage data
- Generate config headers for macOS/Linux
- Compile with coverage instrumentation
- Run tests
- Generate coverage report
./run_coverage.shThis will:
- Configure CMake with
ENABLE_COVERAGE=1 - Build the project
- Run all tests
- Generate HTML coverage report (if lcov/genhtml available)
- GCC or Clang compiler
- gcov (usually included with GCC)
- lcov - Coverage data processing
- genhtml - HTML report generation
Install on macOS:
brew install lcovInstall on Ubuntu/Debian:
sudo apt-get install lcovThe project includes two test suites:
- 315 tests
- Comprehensive testing of core functionality
- IPv6/IPv4 parsing, comparison, conversion
- 36 tests
- Targets previously uncovered code paths
- Edge cases and error handling
gcc -std=c99 -Wall -Wno-long-long -pedantic \
--coverage -O0 -g \
-o ipv6-test ipv6.c test.c./ipv6-testThis generates .gcda files with execution counts.
gcov -b ipv6.cThis creates ipv6.c.gcov with line-by-line coverage.
# Summary
head -5 ipv6.c.gcov
# Find uncovered lines (marked with #####)
grep "^ #####:" ipv6.c.gcov | head -20
# Find partially covered branches (marked with *, -, or numbers)
grep -E "branch.*(never|taken 0%)" ipv6.c.gcov | head -20The .gcov file format:
-: 0:Source:ipv6.c
3: 15: int x = 0; // Executed 3 times
#####: 16: return -1; // Never executed
branch 0 taken 75% // Branch taken 75% of the time
branch 1 taken 25% (fallthrough) // Branch taken 25% of the time
-: Line not executable (comments, declarations)- Number: Execution count
#####: Never executedbranch N taken X%: Branch coverage
To enable coverage in your own CMake build:
mkdir build
cd build
cmake -DENABLE_COVERAGE=1 -DIPV6_PARSE_LIBRARY_ONLY=OFF ..
make
ctestThen generate reports:
cd ..
gcov -b build/CMakeFiles/ipv6-test.dir/ipv6.c.oCurrent coverage status:
- Line Coverage: 89.45% (455 lines)
- Branch Coverage: 98.83% executed, 80.08% taken
- Target: > 90% line and branch coverage
- Core parsing functions: > 95%
- Error handling: > 80%
- Public API: 100%
- Platform-specific code (#ifdef blocks)
- Unreachable error conditions
- Defensive error checks
-
Find uncovered lines:
grep "^ #####:" ipv6.c.gcov -
Check if line is testable:
- Error recovery paths?
- Platform-specific?
- Defensive check?
-
Write test if needed:
- Add to test_extended.c
- Verify coverage improves
The gcov files include the executable name. Try:
gcov -b <executable-name>-ipv6.gcda
# Example: gcov -b ipv6-test-ipv6.gcdaMake sure you run gcov from the directory containing the source files.
Ensure:
- Compiled with
--coverage - Linked with
--coverage - Tests actually ran (check return code)
.gcdafiles were created (ls *.gcda)
-
Clean between runs:
rm -f *.gcda *.gcno *.gcov
-
Test both suites:
./ipv6-test && ./ipv6-test-extended # Then run gcov to see combined coverage
-
Focus on uncovered branches: Branch coverage often reveals edge cases.
-
Don't aim for 100%: 90-95% is excellent for real-world code.
Example GitHub Actions workflow:
- name: Run tests with coverage
run: |
./build_and_test_coverage.sh
- name: Upload coverage
uses: codecov/codecov-action@v3
with:
files: ./ipv6.c.gcovFor issues or questions:
- Check that all prerequisites are installed
- Verify compilation succeeded with
--coverage - Ensure tests ran successfully
- Check file permissions on
.gcdafiles
Coverage tools and scripts: MIT License (same as IPv6-parse)