Skip to content

test: rewrite test suite with native stubs, 86% coverage#223

Merged
TideDra merged 6 commits into
mainfrom
dev
Apr 4, 2026
Merged

test: rewrite test suite with native stubs, 86% coverage#223
TideDra merged 6 commits into
mainfrom
dev

Conversation

@TideDra

@TideDra TideDra commented Apr 4, 2026

Copy link
Copy Markdown
Owner

Summary

Complete test suite overhaul that eliminates Docker dependencies and achieves 86% code coverage:

Test Infrastructure

  • Replace Docker-based mocking (MailHog SMTP, mock OpenAI server) with pure Python stubs using SimpleNamespace and monkeypatch
  • Create tests/canned_responses.py with shared stub factories for OpenAI, Zotero, and SMTP
  • Add session-scoped Hydra config composition with function-scoped deep copies

Test Migration & New Coverage

  • Reorganize all tests to mirror source module structure 1:1
  • Migrate tests from old files (test_glob_match, test_include_path, test_llm, test_email) into module-aligned files
  • Add new tests for previously untested modules: construct_email, main entry point, biorxiv/medrxiv retrievers, base reranker
  • Add E2E test exercising full pipeline: Zotero fetch -> retrieve -> rerank -> TLDR -> email
  • Fix RSS fixture that was causing test_arxiv_retriever to pass vacuously with 0 papers

CI Simplification

  • Remove MailHog and mock_openai Docker service containers from CI workflow
  • Replace @pytest.mark.ci with @pytest.mark.slow for model-download tests
  • Add pytest-cov dev dependency for coverage reporting

Test Coverage

77 tests, 86% coverage. All tests run locally with uv run pytest (no Docker needed).

src/zotero_arxiv_daily/construct_email.py     100%
src/zotero_arxiv_daily/executor.py             97%
src/zotero_arxiv_daily/main.py                 92%
src/zotero_arxiv_daily/protocol.py            100%
src/zotero_arxiv_daily/reranker/api.py        100%
src/zotero_arxiv_daily/reranker/base.py        97%
src/zotero_arxiv_daily/retriever/base.py       95%
src/zotero_arxiv_daily/retriever/biorxiv.py    87%
src/zotero_arxiv_daily/utils.py                91%
TOTAL                                          86%

Pre-Landing Review

No issues found.

Plan Completion

28/28 plan items completed.

Test plan

  • All pytest tests pass (77 passed, 1 deselected)
  • Coverage verified at 86%
  • No @pytest.mark.ci markers remain
  • No unittest.mock imports in test files
  • CI workflow runs without Docker containers

🤖 Generated with Claude Code

TideDra and others added 4 commits April 4, 2026 08:34
Replace Docker-based mocking (MailHog SMTP, mock OpenAI) with pure
Python stub factories using SimpleNamespace and monkeypatch. Create
conftest hierarchy with session-scoped Hydra config composition.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Reorganize tests to mirror source structure. Migrate tests from old
files (test_glob_match, test_include_path, test_llm, test_email) into
module-aligned files. Add new tests for previously untested modules
(construct_email, main, biorxiv/medrxiv retrievers, base reranker).
Add E2E test exercising full pipeline: Zotero -> retrieve -> rerank ->
TLDR -> email. Fix RSS fixture to include "new" announce type entries
so test_arxiv_retriever actually exercises the retriever (was passing
vacuously with 0 papers before). 77 tests total, 86% coverage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Remove MailHog and mock_openai service containers from CI workflow.
Replace @pytest.mark.ci with @pytest.mark.slow for model-download
tests. Add pytest-cov dev dependency. Update CLAUDE.md testing docs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 4, 2026 12:08

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Overhauls the test suite to remove Docker/external-service dependencies by replacing them with pure-Python stubs/fixtures, while adding coverage reporting and simplifying CI.

Changes:

  • Replaced Docker-based OpenAI/SMTP/Zotero mocking with SimpleNamespace + monkeypatch stubs and shared factories.
  • Reorganized tests to mirror the src/zotero_arxiv_daily/ module structure and added new coverage (executor, main, protocol, retrievers, rerankers, email construction).
  • Simplified CI by removing service containers and adding pytest-cov coverage reporting.

Reviewed changes

Copilot reviewed 24 out of 28 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
uv.lock Adds locked dependencies for coverage and pytest-cov to support coverage reporting.
pyproject.toml Switches default marker exclusion to not slow and adds pytest-cov to dev deps.
.github/workflows/ci.yml Removes Docker services and runs pytest with coverage enabled.
CLAUDE.md Adds repo workflow/testing guidance and run commands for contributors/tools.
tests/conftest.py Adds session-scoped Hydra config composition + function-scoped deep copies.
tests/canned_responses.py Centralizes stub factories for OpenAI, Zotero, SMTP + canned API responses.
tests/test_utils.py New tests for utils (glob_match, send_email, extract_tex_code_from_tar).
tests/test_protocol.py New tests for Paper.generate_tldr and Paper.generate_affiliations using stub OpenAI.
tests/test_main.py New tests for main entrypoint behavior via __wrapped__ to bypass Hydra.
tests/test_executor.py New tests for include/ignore path normalization, corpus filtering, Zotero fetch, and E2E Executor.run().
tests/test_construct_email.py New tests for HTML email rendering helpers and empty-email behavior.
tests/retriever/conftest.py Adds retriever-specific fixtures for offline feedparser/requests stubbing.
tests/retriever/test_arxiv_retriever.py Updates arXiv retriever tests to stay offline by mocking arxiv client + extraction.
tests/retriever/test_base_retriever.py Adds tests for base retriever error handling, serial execution, and registration lookup.
tests/retriever/test_biorxiv_retriever.py Adds tests for bioRxiv retriever filtering/convert behavior and required config.
tests/retriever/test_medrxiv_retriever.py Adds tests for medRxiv retriever server/pdf URL composition.
tests/reranker/conftest.py Adds reranker-specific fixture to patch OpenAI import site for API reranker.
tests/reranker/test_api_reranker.py Replaces CI-only test with stubbed OpenAI embedding tests + batching coverage.
tests/reranker/test_base_reranker.py Adds deterministic tests for rerank sorting, time-decay weighting, and unknown reranker lookup.
tests/reranker/test_local_reranker.py Marks local reranker test as slow (model download) and normalizes assertions.
tests/test_llm.py Removes legacy OpenAI-integration tests that required external services/CI marker.
tests/test_email.py Removes legacy email tests that relied on external behavior/CI marker.
tests/test_include_path.py Removes legacy include/ignore path tests migrated into tests/test_executor.py.
tests/test_glob_match.py Removes legacy glob-match tests migrated into tests/test_utils.py.
tests/retriever/arxiv_rss_example.xml Fixes/extends RSS fixture so arXiv tests exercise non-vacuous paper parsing.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread CLAUDE.md

```bash
# Run the application
uv run src/zotero_arxiv_daily/main.py

Copilot AI Apr 4, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

uv run src/zotero_arxiv_daily/main.py is unlikely to work reliably because uv run expects an executable command; a Python file without a shebang/execute bit typically won’t run. Consider documenting uv run python src/zotero_arxiv_daily/main.py or uv run python -m zotero_arxiv_daily.main instead.

Suggested change
uv run src/zotero_arxiv_daily/main.py
uv run python -m zotero_arxiv_daily.main

Copilot uses AI. Check for mistakes.
Comment thread CLAUDE.md
Comment on lines +78 to +81
## Git Workflow

- PRs should target the `dev` branch, not `main`
- Current development branch: `dev`

Copilot AI Apr 4, 2026

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This doc says PRs should target dev, but the CI workflow currently runs only for pushes/PRs against main. Either update the workflow triggers to include dev or clarify here that CI won’t run for PRs targeting dev as-is.

Copilot uses AI. Check for mistakes.
Comment thread .github/workflows/ci.yml
TideDra and others added 2 commits April 4, 2026 20:18
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
@TideDra TideDra merged commit f83b3f9 into main Apr 4, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants