File size: 20,418 Bytes
cc036ff
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
# Coverage Report Interpretation Guide

**Purpose**: Comprehensive guide for interpreting coverage reports and improving test coverage.

**Last Updated**: 2026-02-11

---

## Overview

Code coverage measures how much of your codebase is executed by tests. Coverage reports help identify untested code, track testing progress, and enforce quality standards.

**Key Concepts**:
- **Line Coverage**: Percentage of executable lines executed by tests
- **Branch Coverage**: Percentage of code branches (if/else, try/except) executed by tests
- **Coverage Paradox**: High coverage numbers don't guarantee high quality

**Project Coverage Targets**:
- Overall backend: 80%
- Governance domain: 80%
- Security domain: 80%
- Episodes domain: 80%

---

## Coverage Metrics Explained

### Line Coverage vs Branch Coverage

**Line Coverage** measures which lines of code were executed:
```

def check_permission(user, action):

    if user.is_admin:           # Line 1

        return True              # Line 2

    return False                 # Line 3

```

If tests only call `check_permission(admin_user, "read")`:
- Line coverage: 67% (lines 1-2 executed, line 3 not executed)
- Branch coverage: 50% (only "if" branch tested, "else" branch not tested)

**Branch Coverage** is more accurate because it measures all possible execution paths:
- If statements: 2 branches (true, false)
- Try/except: 2 branches (success, exception)
- Short-circuit operators: 2 branches (or, and)

**Why Branch Coverage Matters**:
```python

# Line coverage: 100%, Branch coverage: 50%

def divide(a, b):

    if b != 0 and a / b > 10:   # Both lines executed

        return "large"

    return "small"



# Test: divide(20, 2) → lines 1-3 executed

# Missing: divide(10, 0) → exception path not tested

```

**Recommendation**: Always enable branch coverage with `--cov-branch` flag (already in pytest.ini).

---

### Coverage Percentage Interpretation

| Coverage Range | Interpretation | Action |
|----------------|----------------|--------|
| 0-20% | Untested codebase | Start with critical paths |
| 20-50% | Early testing | Focus on core functionality |
| 50-80% | Good coverage | Target for most projects |
| 80-90% | Excellent coverage | Diminishing returns above 80% |
| 90-100% | Near-perfect | Risk of over-testing |

**Diminishing Returns Above 90%**:
- Last 10% costs 50% of testing effort
- Focus on critical paths first
- 100% coverage is rarely practical

**When 80% is Sufficient**:
- Error handling is tested
- Critical paths covered
- Property tests validate invariants
- Integration tests cover workflows

---

### Coverage Paradox

**High Coverage, Low Quality**: Tests cover lines but not scenarios.

**Example**:
```python

# Line coverage: 100%, Branch coverage: 100%

# Quality: LOW (no assertions verify correctness)



def calculate_discount(price, user):

    if user.is_vip:

        return price * 0.9

    return price



def test_calculate_discount():

    calculate_discount(100, vip_user)    # Line covered

    calculate_discount(100, regular_user) # Line covered

    # No assertions! Bugs would pass silently.

```

**Detection Strategies**:
1. **Property-based tests**: Validate invariants across all inputs (Hypothesis)
2. **Mutation testing**: Detect weak tests (mutmut)
3. **Assertion density**: Track assertions per line (conftest.py)

**See**: `property_tests/INVARIANTS.md` for property test patterns.

---

### Missing Coverage

**0% Coverage Means**:
- No tests execute this code
- Untested bugs may exist
- Refactoring is risky

**Common Causes**:
1. **Dead code**: Unused functions (consider removing)
2. **Error paths**: Exception handlers not tested
3. **Edge cases**: Boundary conditions not covered
4. **New code**: Written without tests

**Priority for Improving Coverage**:
1. **Critical paths**: Authentication, authorization, payments
2. **Security**: Input validation, encryption, access control
3. **Data integrity**: Database operations, transactions
4. **User-facing**: API endpoints, business logic

---

## Reading Coverage Reports

### HTML Report Navigation

**Location**: `backend/tests/coverage_reports/html/index.html`

**Usage**:
```bash

# Generate HTML report

pytest tests/ --cov=core --cov=api --cov=tools --cov-report=html



# Open in browser

open tests/coverage_reports/html/index.html

```

**Interpretation**:
- **Green**: >80% coverage (good)
- **Yellow**: 50-80% coverage (needs improvement)
- **Red**: <50% coverage (critical gaps)

**HTML Report Features**:
- Click directory to see files
- Click file to see line-by-line coverage
- Red lines = not executed
- Yellow lines = partially executed (branch coverage)

---

### JSON Report Structure

**Location**: `backend/tests/coverage_reports/metrics/coverage.json`

**Format**:
```json

{

  "meta": {

    "timestamp": "2026-02-11T10:30:00",

    "branch_coverage": true,

    "show_contexts": true

  },

  "totals": {

    "covered_lines": 2340,

    "num_statements": 15000,

    "percent_covered": 15.6,

    "covered_branches": 1200,

    "num_branches": 3000,

    "percent_covered_branch": 40.0

  },

  "files": {

    "core/agent_governance_service.py": {

      "summary": {

        "percent_covered": 45.2,

        "percent_covered_branch": 30.0

      },

      "executed_lines": [10, 11, 15, 20],

      "missing_lines": [25, 30, 35],

      "excluded_lines": [1, 2, 3]

    }

  }

}

```

**Key Fields**:
- `percent_covered`: Line coverage percentage
- `percent_covered_branch`: Branch coverage percentage
- `missing_lines`: Line numbers not executed
- `executed_lines`: Line numbers executed

**Usage in CI/CD**:
```bash

# Extract coverage percentage

COVERAGE=$(jq '.totals.percent_covered' tests/coverage_reports/metrics/coverage.json)



# Fail if below threshold

if (( $(echo "$COVERAGE < 80" | bc -l) )); then

    echo "Coverage $COVERAGE% below 80% threshold"

    exit 1

fi

```

---

### Terminal Report Interpretation

**Generate Terminal Report**:
```bash

pytest tests/ --cov-report=term-missing

```

**Output Format**:
```

Name                                         Stmts   Miss  Cover   Missing

------------------------------------------------------------------------

core/agent_governance_service.py               150     75    50%   23-45, 89-102

core/models.py                                 300    120    60%   156-189, 234-267

api/auth_routes.py                              50     40    20%   12-35, 67-89

------------------------------------------------------------------------

TOTAL                                          500    235    53%

```

**Columns**:
- `Stmts`: Total executable statements
- `Miss`: Statements not executed
- `Cover`: Coverage percentage
- `Missing`: Line ranges not covered

**Color Coding**:
- Green: >80%
- Yellow: 50-80%
- Red: <50%

---

## Coverage by Domain

### Governance Domain

**Target**: 80%
**Current**: 13.37% (as of 2026-02-11)

**Files**:
- `agent_governance_service.py` - Agent lifecycle and permissions
- `agent_context_resolver.py` - Agent resolution
- `governance_cache.py` - High-performance caching
- `trigger_interceptor.py` - Maturity-based trigger routing

**Priority Tests**:
1. Maturity threshold enforcement (STUDENT agents block high-complexity actions)
2. Confidence-based routing (low confidence → supervised)
3. Permission checks (all 4x4 maturity/complexity combinations)

**Impact**: Governance failures cause unauthorized actions or security violations.

---

### Security Domain

**Target**: 80%
**Current**: 22.40% (as of 2026-02-11)

**Files**:
- `auth_routes.py` - Authentication endpoints
- `encryption.py` - Data encryption/decryption
- `validation.py` - Input validation

**Priority Tests**:
1. JWT token validation (expired, invalid, malformed)
2. Password hashing (bcrypt, salt rounds)
3. Input validation (OWASP Top 10 payloads)
4. SQL injection prevention (parameterized queries)

**Impact**: Security failures cause unauthorized access or data breaches.

---

### Episodes Domain

**Target**: 80%
**Current**: 15.52% (as of 2026-02-11)

**Files**:
- `episode_segmentation_service.py` - Episode creation
- `episode_retrieval_service.py` - Episode retrieval
- `episode_lifecycle_service.py` - Episode lifecycle
- `agent_graduation_service.py` - Graduation validation

**Priority Tests**:
1. Time gap detection (boundaries, thresholds)
2. Semantic retrieval (similarity, ranking)
3. Graduation criteria (episode count, intervention rate)
4. Constitutional compliance (intervention tracking)

**Impact**: Episode failures cause incorrect agent learning or premature promotion.

---

### Backend Overall

**Target**: 80%
**Current**: 15.57% (as of 2026-02-11)

**Files Tracked**: 401 files

**Breakdown**:
- Governance: 13.37%
- Security: 22.40%
- Episodes: 15.52%
- Other domains: Variable

**Focus Areas**:
1. Critical paths: Auth, governance, payments
2. Error handling: Exception paths, edge cases
3. Integration points: API endpoints, database operations

---

## Coverage Trending

### Tracking Coverage Over Time

**Purpose**: Detect coverage regressions and measure progress.

**Location**: `backend/tests/coverage_reports/trends/coverage_trend.json`

**Format**:
```json

{

  "coverage_history": [

    {

      "date": "2026-02-11",

      "commit": "abc123",

      "overall_percent": 15.57,

      "governance_percent": 13.37,

      "security_percent": 22.40,

      "episodes_percent": 15.52

    }

  ],

  "targets": {

    "overall": 80,

    "governance": 80,

    "security": 80,

    "episodes": 80

  }

}

```

**Usage**:
```bash

# View trend

jq '.coverage_history[] | .date + ": " + (.overall_percent | tostring) + "%"' \

  tests/coverage_reports/trends/coverage_trend.json



# Detect regression

LATEST=$(jq '.coverage_history[0].overall_percent' coverage_trend.json)

PREVIOUS=$(jq '.coverage_history[1].overall_percent' coverage_trend.json)



if (( $(echo "$LATEST < $PREVIOUS" | bc -l) )); then

    echo "Coverage regression detected: $PREVIOUS% → $LATEST%"

fi

```

---

### Detecting Coverage Regressions

**Regression**: Coverage decreases between commits.

**CI/CD Check**:
```yaml

# .github/workflows/coverage-report.yml

- name: Check coverage regression

  run: |

    LATEST=$(jq '.coverage_history[0].overall_percent' coverage_trend.json)

    PREVIOUS=$(jq '.coverage_history[1].overall_percent' coverage_trend.json)

    THRESHOLD=1.0  # 1% tolerance



    if (( $(echo "$PREVIOUS - $LATEST > $THRESHOLD" | bc -l) )); then

      echo "Coverage regression: $PREVIOUS% → $LATEST%"

      exit 1

    fi

```

**Common Causes**:
1. Deleted tests without replacement
2. Refactored code without updating tests
3. New code written without tests

---

### Coverage Thresholds and Quality Gates

**Quality Gate**: Minimum coverage requirement for PR approval.

**Configuration** (pytest.ini):
```ini

[pytest]

cov_fail_under = 80

```

**CI/CD Enforcement**:
```yaml

- name: Run tests with coverage

  run: pytest tests/ --cov=core --cov=api --cov=tools --cov-fail-under=80

```

**Per-Domain Thresholds**:
```python

# conftest.py

def pytest_terminal_summary(terminalreporter):

    coverage_data = json.load(open("coverage.json"))



    governance_cov = coverage_data['files']['core/agent_governance_service.py']['summary']['percent_covered']

    if governance_cov < 80:

        terminalreporter.write_line(f"ERROR: Governance coverage {governance_cov}% below 80%", red=True)

```

**Recommendation**: Start with 60% threshold, increase to 80% as coverage improves.

---

## Improving Coverage

### Identifying Uncovered Lines

**Step 1: Generate HTML Report**
```bash

pytest tests/ --cov=core --cov=api --cov=tools --cov-report=html

open tests/coverage_reports/html/index.html

```

**Step 2: Find Red Files**
- Click through directories
- Look for files with <80% coverage
- Click file to see line-by-line breakdown

**Step 3: Analyze Missing Lines**
- Red lines = not executed
- Yellow lines = partially executed (branch coverage)
- Right-click line → "show context" to see why it's not covered

---

### Prioritizing Coverage Gaps

**Priority Matrix**:

| Impact | High Coverage | Low Coverage | Action |
|--------|---------------|--------------|--------|
| **Critical** | Error in test | **IMMEDIATE** | Fix tests |
| **High** | Monitor | **HIGH** | Add tests |
| **Medium** | Defer | **MEDIUM** | Add tests |
| **Low** | Accept | **LOW** | Document |

**Critical Paths** (test first):
1. Authentication: Login, logout, token refresh
2. Authorization: Permission checks, maturity enforcement
3. Data integrity: Database transactions, validation
4. Security: Encryption, input validation, access control

**Example Priority**:
```python

# CRITICAL: Auth bypass

if user.is_admin:  # Branch coverage: 50% → Fix immediately

    return sensitive_data



# HIGH: Business logic

if discount > 0.9:  # Branch coverage: 75% → Add test

    apply_discount()



# MEDIUM: Edge case

if user.preferences.color == "blue":  # Branch coverage: 0% → Defer

    set_theme("blue")

```

---

### Writing Tests for Uncovered Code

**Step 1: Understand What's Missing**
```python

# Original code (lines 25-30 not covered)

def delete_agent(agent_id, user):

    if not user.is_admin:          # Line 25

        raise PermissionError()     # Line 26

    agent = db.get(agent_id)        # Line 27

    if agent.status == "ACTIVE":    # Line 28

        raise ValueError()          # Line 29

    db.delete(agent)                # Line 30

```

**Step 2: Write Test for Missing Path**
```python

def test_delete_agent_requires_admin(unique_resource_name):

    """Test non-admin cannot delete agents (line 25-26)."""

    user = UserFactory.create(role="member")  # Not admin

    agent = AgentFactory.create(id=unique_resource_name)



    with pytest.raises(PermissionError):

        delete_agent(agent.id, user)



def test_delete_active_agent_fails(unique_resource_name):

    """Test deleting active agent raises error (line 28-29)."""

    admin = UserFactory.create(role="admin")

    agent = AgentFactory.create(id=unique_resource_name, status="ACTIVE")



    with pytest.raises(ValueError):

        delete_agent(agent.id, admin)



def test_delete_inactive_agent_succeeds(unique_resource_name):

    """Test deleting inactive agent works (line 30)."""

    admin = UserFactory.create(role="admin")

    agent = AgentFactory.create(id=unique_resource_name, status="INACTIVE")



    delete_agent(agent.id, admin)

    assert db.get(agent.id) is None

```

**Step 3: Run Tests**
```bash

pytest tests/test_agent_service.py -v --cov=core/agent_service --cov-report=term-missing

```

**Step 4: Verify Coverage Improved**
- Check HTML report
- Lines 25-30 should now be green

---

### When NOT to Chase 100% Coverage

**Exclusions from Coverage Targets**:

1. **Generated Code**:
   - Protobuf-generated files
   - OpenAPI-generated models
   - Database migration scripts

2. **Configuration**:
   - Constants, enums
   - Environment variable loading
   - Logging configuration

3. **Third-Party Wrappers**:
   - Thin wrappers around libraries
   - Adapter classes (1-2 lines)

4. **Impossible Paths**:
   - OS-specific code (Windows tests on Mac)
   - Hardware-dependent code
   - GUI code in CI/CD

**Example .coveragerc**:
```ini

[report]

exclude_lines =

    pragma: no cover

    def __repr__

    raise AssertionError

    raise NotImplementedError

    if __name__ == .__main__.:

    if TYPE_CHECKING:

    @abstractmethod

```

**Guideline**: 80% coverage is practical. 100% coverage is rarely worth the cost.

---

## Coverage Tools Reference

### pytest-cov Command Reference

**Basic Usage**:
```bash

# Run tests with coverage

pytest tests/ --cov=core



# Multiple modules

pytest tests/ --cov=core --cov=api --cov=tools



# Generate reports

pytest tests/ --cov=core --cov-report=html --cov-report=json --cov-report=term

```

**Report Formats**:
- `--cov-report=html`: HTML report (coverage_reports/html/index.html)

- `--cov-report=json`: JSON report (coverage.json)

- `--cov-report=term`: Terminal output

- `--cov-report=term-missing`: Terminal with missing lines



**Branch Coverage**:

```bash

pytest tests/ --cov=core --cov-branch

```



**Coverage Fail Threshold**:

```bash

pytest tests/ --cov=core --cov-fail-under=80

```



**Source Configuration**:

```bash

pytest tests/ --cov=core --cov-context=test

```



---



### Coverage.py CLI Reference



**Combine Coverage Data**:

```bash

# Run tests in parallel

pytest tests/ -n auto --cov=core --cov-parallel



# Combine .coverage files

coverage combine

```



**Generate Report After Tests**:

```bash

pytest tests/ --cov=core

coverage html    # Generate HTML

coverage report  # Generate terminal

coverage json    # Generate JSON

```



**Debug Coverage**:

```bash

coverage debug sys

coverage debug config

```



**Erase Coverage Data**:

```bash

coverage erase  # Delete .coverage file

```



---



### Codecov/Coveralls Integration



**Codecov Upload** (via GitHub Actions):

```yaml

- name: Upload to Codecov

  uses: codecov/codecov-action@v4

  with:

    files: ./tests/coverage_reports/metrics/coverage.json
    flags: backend

    name: backend-coverage

    fail_ci_if_error: false  # Don't fail CI if Codecov is down

```


**Coveralls Upload** (alternative):
```yaml

- name: Upload to Coveralls

  uses: coverallsapp/github-action@v2

  with:

    github-token: ${{ secrets.GITHUB_TOKEN }}

    path-to-lcov: ./coverage.lcov

```

**Benefits**:
- Historical trending dashboard
- PR comments with coverage diff
- File-by-file coverage breakdown
- Coverage badges for README

**Alternative**: Git-tracked JSON (no external service needed)

---

## Related Documentation

- **[TEST_ISOLATION_PATTERNS.md](./TEST_ISOLATION_PATTERNS.md)** - Test isolation patterns and examples
- **[FLAKY_TEST_GUIDE.md](./FLAKY_TEST_GUIDE.md)** - Flaky test prevention and fixing
- **[../property_tests/INVARIANTS.md](../property_tests/INVARIANTS.md)** - Property test invariants
- **[../factories/README.md](../factories/README.md)** - Test data factory usage
- **[../TESTING_GUIDE.md](../TESTING_GUIDE.md)** - Comprehensive testing guide

---

## Summary

**Key Takeaways**:
1. **Branch coverage > Line coverage**: Always use `--cov-branch`
2. **80% is practical**: Diminishing returns above 90%
3. **Coverage paradox**: High coverage ≠ high quality (use property tests)
4. **Trending matters**: Track coverage over time to detect regressions
5. **Prioritize critical paths**: Auth, governance, security first

**Quick Reference**:
```bash

# Generate all reports

pytest tests/ --cov=core --cov=api --cov=tools \

  --cov-branch \

  --cov-report=html \

  --cov-report=json \

  --cov-report=term-missing



# Check coverage trend

jq '.coverage_history[0]' tests/coverage_reports/trends/coverage_trend.json



# View HTML report

open tests/coverage_reports/html/index.html

```

**Next Steps**:
1. Generate coverage report for your domain
2. Identify files <80% coverage
3. Write tests for critical paths first
4. Track coverage in CI/CD
5. Review coverage trends weekly

## See Also

### Platform-Specific Testing Guides

- [Frontend Testing Guide](../../docs/FRONTEND_TESTING_GUIDE.md) - Jest, React Testing Library, MSW patterns
- [Mobile Testing Guide](../../docs/MOBILE_TESTING_GUIDE.md) - jest-expo, React Native Testing Library
- [Desktop Testing Guide](../../docs/DESKTOP_TESTING_GUIDE.md) - cargo test, proptest, tarpaulin

### Related Documentation

- [Testing Documentation Index](../../docs/TESTING_INDEX.md) - Central hub for all testing documentation
- [Testing Onboarding Guide](../../docs/TESTING_ONBOARDING.md) - 15-minute quick start for all platforms
- [Coverage Trending Guide](COVERAGE_TRENDING_GUIDE.md) - 30-day trending and regression detection
- [Flaky Test Quarantine](FLAKY_TEST_QUARANTINE.md) - Multi-run flaky detection and tracking