Skip to content

Achieve 100% unit test coverage #242

@KRRT7

Description

@KRRT7

Goal

Establish a coverage baseline, fix the existing coverage configuration, integrate coverage into CI, and incrementally grow to 100% unit test coverage.

Current state

The repo has a solid test suite (~39 test files) but no visibility into what's actually covered. The pieces for coverage are partially in place but misconfigured:

What exists

  • .coveragerc — present but source = test measures the test code, not the source code
  • coverage[toml] — already in dev dependencies
  • make coverage — exists in the Makefile

What's missing or broken

  1. .coveragerc source is wrong — should be source = src/typeagent to measure the actual library, not the tests
  2. CI doesn't run coverageci.yml runs make test but never make coverage, so there's no visibility into coverage on PRs
  3. No coverage floor — nothing prevents coverage from regressing between PRs
  4. No per-module breakdown — no way to see which subpackages (knowpro/, aitools/, storage/, mcp/, podcasts/, emails/, transcripts/) need attention

Suggested plan

Phase 0 — Fix infrastructure and establish baseline

  1. Fix .coveragerc:

    [run]
    branch = true
    source = src/typeagent
    
    [report]
    sort = cover
    show_missing = true
    fail_under = <baseline>  # set after first run
    
    [html]
    directory = htmlcov
  2. Run make coverage locally to get the baseline number, then set fail_under to that value

  3. Add coverage to CI — update ci.yml to run coverage on at least one matrix entry (e.g., ubuntu + py3.14) and upload the report as an artifact or to a service like Codecov

  4. Add an omit pattern for files that are hard to unit test:

    omit =
        src/typeagent/mcp/server.py  # if it's just an entry point

Phase 1 — Identify gaps

Run coverage and create sub-issues per subpackage based on actual numbers:

  • src/typeagent/knowpro/ — core indexing/querying (likely partially covered)
  • src/typeagent/aitools/ — AI tooling (may need mocked LLM calls)
  • src/typeagent/storage/ — storage providers (partially covered via test_storage_providers_unified.py, test_sqlitestore.py)
  • src/typeagent/mcp/ — MCP server (covered by test_mcp_server.py)
  • src/typeagent/podcasts/ — podcast processing (covered by test_podcasts.py, test_podcast_incremental.py)
  • src/typeagent/emails/ — email import
  • src/typeagent/transcripts/ — transcript handling

Phase 2 — Fill gaps incrementally

One PR per subpackage, each must maintain or increase the coverage floor. After each merge, ratchet fail_under up.

Phase 3 — Reach 100%

Mop up remaining branches, edge cases, and error paths.

Principles

  • Ratchet, don't regressfail_under in .coveragerc should be bumped after each coverage PR so the floor only goes up
  • Measure source, not tests — coverage should track src/typeagent, not tests/
  • Mock external services — AI API calls, Azure auth, and email providers should be mocked for offline unit tests
  • Fast and isolated — unit tests should run without network access or API keys (the existing offline/online split is a good pattern to keep)
  • Branch coveragebranch = true is already set, keep it — it catches missed conditional paths that statement coverage misses

Quick start

# Fix .coveragerc source, then:
make coverage
# Look at the total % and per-file breakdown
# Set fail_under to the current total

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions