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
.coveragerc source is wrong — should be source = src/typeagent to measure the actual library, not the tests
- CI doesn't run coverage —
ci.yml runs make test but never make coverage, so there's no visibility into coverage on PRs
- No coverage floor — nothing prevents coverage from regressing between PRs
- 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
-
Fix .coveragerc:
[run]
branch = true
source = src/typeagent
[report]
sort = cover
show_missing = true
fail_under = <baseline> # set after first run
[html]
directory = htmlcov
-
Run make coverage locally to get the baseline number, then set fail_under to that value
-
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
-
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 regress —
fail_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 coverage —
branch = 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
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 butsource = testmeasures the test code, not the source codecoverage[toml]— already in dev dependenciesmake coverage— exists in the MakefileWhat's missing or broken
.coveragercsourceis wrong — should besource = src/typeagentto measure the actual library, not the testsci.ymlrunsmake testbut nevermake coverage, so there's no visibility into coverage on PRsknowpro/,aitools/,storage/,mcp/,podcasts/,emails/,transcripts/) need attentionSuggested plan
Phase 0 — Fix infrastructure and establish baseline
Fix
.coveragerc:Run
make coveragelocally to get the baseline number, then setfail_underto that valueAdd coverage to CI — update
ci.ymlto 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 CodecovAdd an omit pattern for files that are hard to unit test:
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 viatest_storage_providers_unified.py,test_sqlitestore.py)src/typeagent/mcp/— MCP server (covered bytest_mcp_server.py)src/typeagent/podcasts/— podcast processing (covered bytest_podcasts.py,test_podcast_incremental.py)src/typeagent/emails/— email importsrc/typeagent/transcripts/— transcript handlingPhase 2 — Fill gaps incrementally
One PR per subpackage, each must maintain or increase the coverage floor. After each merge, ratchet
fail_underup.Phase 3 — Reach 100%
Mop up remaining branches, edge cases, and error paths.
Principles
fail_underin.coveragercshould be bumped after each coverage PR so the floor only goes upsrc/typeagent, nottests/branch = trueis already set, keep it — it catches missed conditional paths that statement coverage missesQuick start