← Home ← Codex ← DEBT
Browse by Category
+ added · updated 7d
← Back to glossary

Code Coverage

Testing PHP 5.0+ Beginner
debt(d5/e3/b5/t7)
d5 Detectability Operational debt — how invisible misuse is to your safety net

Closest to 'specialist tool catches it' (d5). Tools listed — phpunit, xdebug, pcov, infection, codecov — are specialist coverage and mutation-testing tools that can surface untested paths and meaningless assertions. However, the core misuse (tests that execute lines without asserting behaviour) is not caught by a default linter; it requires deliberate use of mutation testing (Infection) or careful review of test quality, placing it squarely in specialist-tool territory rather than compiler or default-linter detection.

e3 Effort Remediation debt — work required to fix once spotted

Closest to 'simple parameterised fix' (e3). The quick_fix indicates adopting PHPUnit with Xdebug/PCOV and adding mutation testing via Infection — a modest tooling and configuration change. However, fixing the underlying common mistake (meaningless tests written to hit a coverage target) requires rewriting those tests to include meaningful assertions, which is more than a one-liner but typically contained within the test suite rather than spanning the entire codebase.

b5 Burden Structural debt — long-term weight of choosing wrong

Closest to 'persistent productivity tax' (b5). Coverage targets and metrics apply across web, cli, and queue-worker contexts (per applies_to) and influence every test-writing decision across the project. A bad coverage culture (chasing 100%, ignoring mutation testing) persistently slows down meaningful QA work and misleads teams about code quality, affecting many work streams without necessarily being architecturally load-bearing.

t7 Trap Cognitive debt — how counter-intuitive correct behaviour is

Closest to 'serious trap' (t7). The misconception field is explicit: '100% code coverage means the code is fully tested' — a deeply held wrong belief that contradicts how the metric actually works. Coverage measures line execution, not correctness of assertions. This contradicts how developers reason about testing in other contexts (e.g. passing tests imply correct behaviour), making it a serious trap that experienced developers across ecosystems commonly fall into.

About DEBT scoring →

Also Known As

test coverage line coverage branch coverage

TL;DR

A metric measuring the percentage of code executed by a test suite — useful for identifying untested paths, not a quality guarantee.

Explanation

Code coverage (line, branch, path, mutation) measures which code was executed during tests. PHPUnit integrates with Xdebug or PCOV to generate coverage reports. High coverage does not guarantee correctness — tests can execute code without asserting meaningful outcomes. Mutation testing (Infection PHP) goes further, introducing bugs into the code and checking whether tests fail. Rather than chasing 100% line coverage, focus coverage efforts on business logic, security-sensitive code, and complex conditionals where untested branches pose real risk.

Diagram

flowchart TD
    subgraph Coverage_Types
        LINE[Line coverage<br/>was each line executed]
        BRANCH[Branch coverage<br/>was each if/else path taken]
        MUT2[Mutation coverage<br/>do tests catch changes]
    end
    subgraph Pitfalls
        FALSE_100[100pct line coverage<br/>but no assertions<br/>tests nothing]
        METRIC[Coverage as a target<br/>Goodharts Law - gaming it]
    end
    subgraph Better_Goal
        MEANINGFUL[Meaningful assertions<br/>test behaviours not lines]
        MUTATION[High mutation score<br/>tests actually catch bugs]
    end
style FALSE_100 fill:#f85149,color:#fff
style METRIC fill:#f85149,color:#fff
style MEANINGFUL fill:#238636,color:#fff
style MUTATION fill:#238636,color:#fff

Common Misconception

100% code coverage means the code is fully tested. Coverage measures which lines execute during tests, not whether the tests assert meaningful outcomes. A test that calls every line without asserting anything achieves 100% coverage and proves nothing.

Why It Matters

Coverage metrics show which code is exercised by tests — they reveal untested paths and give a floor for confidence. However, 100% coverage does not mean the code is correct, only that every line was executed at least once.

Common Mistakes

  • Setting 100% coverage as a target — teams write meaningless tests just to hit the number.
  • Counting coverage on generated code, migrations, and config files — only measure what matters.
  • Using line coverage instead of branch coverage — a line with an if can be covered without testing the false path.
  • Treating coverage as sufficient QA — coverage measures quantity of testing, not quality.

Code Examples

💡 Note
100% coverage is not the goal — meaningful tests covering real behaviour are. A poorly written test can hit a line without actually asserting anything.
✗ Vulnerable
// Test that covers code without testing behaviour:
public function testUserCreation(): void {
    $user = new User('Alice', 'alice@example.com');
    $this->assertInstanceOf(User::class, $user); // Just checks the object was created
    // 100% line coverage — zero meaningful assertion about User's behaviour
}
✓ Fixed
# phpunit.xml — require 80% line coverage on CI
<coverage>
  <report>
    <clover outputFile='build/coverage.xml'/>
    <html outputDirectory='build/coverage-html'/>
  </report>
</coverage>

# Enforce minimum in CI
$ phpunit --coverage-clover=coverage.xml
$ php vendor/bin/coverage-check coverage.xml 80

Added 15 Mar 2026
Edited 22 Mar 2026
Views 78
Rate this term
No ratings yet
🤖 AI Guestbook educational data only
| |
Last 30 days
0 pings T 0 pings W 1 ping T 0 pings F 2 pings S 0 pings S 0 pings M 0 pings T 0 pings W 1 ping T 3 pings F 0 pings S 5 pings S 2 pings M 1 ping T 0 pings W 0 pings T 0 pings F 0 pings S 0 pings S 0 pings M 0 pings T 0 pings W 0 pings T 0 pings F 1 ping S 1 ping S 1 ping M 0 pings T 0 pings W
No pings yet today
No pings yesterday
Amazonbot 16 Perplexity 10 Scrapy 10 Ahrefs 5 SEMrush 4 ChatGPT 3 Unknown AI 3 Google 3 Majestic 2 Meta AI 2 Claude 2 Bing 2 Qwen 1 PetalBot 1
crawler 60 crawler_json 3 pre-tracking 1
DEV INTEL Tools & Severity
🟡 Medium ⚙ Fix effort: Medium
⚡ Quick Fix
Use PHPUnit with Xdebug or PCOV for coverage — aim for 80% line coverage on business logic; use mutation testing (Infection) to verify the coverage is meaningful
📦 Applies To
PHP 5.0+ web cli queue-worker
🔗 Prerequisites
🔍 Detection Hints
0% test coverage on critical payment or auth code; coverage target met with assertions that don't verify behaviour; no mutation testing
Auto-detectable: ✓ Yes phpunit xdebug pcov infection codecov
⚠ Related Problems
🤖 AI Agent
Confidence: Medium False Positives: Medium ✗ Manual fix Fix: Medium Context: File Tests: Update


✓ schema.org compliant