Skip to main content

coverage-analysis

Use when measuring test coverage for Solidity contracts, identifying untested code paths, or establishing coverage requirements. Covers forge coverage, lcov output, visualization, and coverage-driven testing.

Informations de source

Dépôt
ccashwell/evm-cortex
Dernière activité de la source
10 avril 2026 à 16:31
Langue détectée de SKILL.md
anglais
Étoiles
131
Forks
18

Options d'installation

Le prompt qui vérifie d'abord la source est sélectionné par défaut. Vous pouvez passer à une commande directe ou télécharger une copie locale.

Vérifiez les fichiers source

Lisez SKILL.md et les fichiers associés affichés par SkillsMP avant de décider de l'installer.

Affichage de SKILL.md

SKILL.md
Instructions source · Aperçu en lecture seule
name
coverage-analysis
description
Use when measuring test coverage for Solidity contracts, identifying untested code paths, or establishing coverage requirements. Covers forge coverage, lcov output, visualization, and coverage-driven testing.
# Test Coverage Analysis ## Running Coverage ```bash # Basic coverage report forge coverage # Output: # | File | % Lines | % Statements | % Branches | % Functions | # |--------------------|-----------------|-----------------|-----------------|-----------------| # | src/Vault.sol | 92.31% (36/39) | 89.47% (34/38) | 75.00% (12/16) | 100.00% (8/8) | # | src/Token.sol | 100.00% (12/12) | 100.00% (10/10) | 100.00% (4/4) | 100.00% (3/3) | ``` ## LCOV Output for Visualization ```bash # Generate lcov.info forge coverage --report lcov # View in VS Code with "Coverage Gutters" extension # Or generate HTML report: genhtml lcov.info -o coverage-report --branch-coverage open coverage-report/index.html ``` ## Coverage Types | Type | Meaning | Priority | |------|---------|----------| | **Line** | Was this line executed? | Medium | | **Statement** | Was this statement executed? | Medium | | **Branch** | Were both sides of if/else taken? | **High** | | **Function** | Was this function called? | Low | Branch coverage is the most important for security — untested branches are where bugs hide. ## Filtering Coverage ```bash # Exclude test files and scripts forge coverage --report lcov # Filter the lcov output lcov --remove lcov.info 'test/*' 'script/*' 'node_modules/*' \ --output-file lcov-filtered.info ``` ## Coverage-Driven Testing Workflow ### 1. Identify Gaps ```bash # Generate and inspect coverage forge coverage --report lcov genhtml lcov.info -o coverage-report --branch-coverage ``` ### 2. Focus on Uncovered Branches For each uncovered branch, write a targeted test: ```solidity // If coverage shows this branch is untested: // if (amount > maxDeposit) revert ExceedsMax(); function test_depositExceedsMax() public { uint256 maxDeposit = vault.maxDeposit(address(this)); vm.expectRevert(abi.encodeWithSelector(ExceedsMax.selector)); vault.deposit(maxDeposit + 1, address(this)); } ``` ### 3. Common Untested Paths ```solidity // Zero-amount edge cases function test_depositZero() public { vm.expectRevert("zero amount"); vault.deposit(0, address(this)); } // Reentrancy guard activation function test_reentrancyBlocked() public { attacker.setReentrancy(true); vm.expectRevert("ReentrancyGuard: reentrant call"); attacker.attack(); } // Overflow/underflow (checked math reverts) function test_overflowReverts() public { vm.expectRevert(); vault.deposit(type(uint256).max, address(this)); } // Access control all roles function test_onlyOwnerFunctions() public { vm.prank(nonOwner); vm.expectRevert(); vault.setFee(100); } // Pause/unpause paths function test_pausedDeposit() public { vault.pause(); vm.expectRevert("Pausable: paused"); vault.deposit(1 ether, address(this)); } ``` ## CI Integration ```yaml - name: Check coverage threshold run: | forge coverage --report summary | tee coverage.txt # Parse line coverage percentage COVERAGE=$(grep "| Total" coverage.txt | awk '{print $4}' | tr -d '%') if (( $(echo "$COVERAGE < 85" | bc -l) )); then echo "Coverage $COVERAGE% is below 85% threshold" exit 1 fi ``` ## Coverage Report in `foundry.toml` ```toml [profile.default] # Exclude from coverage analysis no_match_coverage = "test|script|mock" ``` ## Coverage Targets by Component | Component | Minimum | Target | |-----------|---------|--------| | Core protocol logic | 95% branch | 100% branch | | Token contracts | 90% branch | 100% branch | | Admin/governance | 85% branch | 95% branch | | Periphery/helpers | 80% branch | 90% branch | | View functions | 70% line | 85% line | ## Limitations - Coverage does not measure test quality — 100% coverage doesn't mean 100% correct - Foundry coverage doesn't handle inline assembly well - Branch coverage inside `require()` chains may not report correctly - Coverage overhead slows test execution (separate coverage CI step) - Unreachable code (dead branches) inflates uncovered percentage ## Checklist - [ ] `forge coverage` runs in CI on every PR - [ ] LCOV report generated for visual inspection - [ ] Branch coverage prioritized over line coverage - [ ] Coverage threshold enforced (85%+ for core contracts) - [ ] Test and script files excluded from coverage stats - [ ] Uncovered branches documented as known gaps or addressed - [ ] Coverage report reviewed during audit preparation - [ ] New features include tests that maintain/improve coverage
Voir sur GitHub