Skip to content

Commit c79d5d2

Browse files
add doc coverage
1 parent b5b9304 commit c79d5d2

4 files changed

Lines changed: 245 additions & 2 deletions

File tree

.github/workflows/tests.yaml

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,5 +34,18 @@ jobs:
3434
# They're tagged `@pytest.mark.network` and skipped here. The plan is
3535
# to shim those with mocks; once a test no longer needs a real server,
3636
# drop the marker and it will run in CI automatically.
37-
- name: Run pytest
38-
run: uv run --python ${{ matrix.python-version }} pytest -v -m "not network"
37+
- name: Run pytest with coverage
38+
run: |
39+
uv run --python ${{ matrix.python-version }} pytest -v \
40+
-m "not network" \
41+
--cov --cov-report=term --cov-report=xml
42+
43+
# Keep coverage.xml around so a later badge/Codecov upload step can use it.
44+
- name: Upload coverage report artifact
45+
if: always()
46+
uses: actions/upload-artifact@v4
47+
with:
48+
name: coverage-${{ matrix.python-version }}
49+
path: coverage.xml
50+
if-no-files-found: warn
51+
retention-days: 7

README.md

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,60 @@ Links:
99
* [Architecture Doc](https://docs.google.com/document/d/1pIaeQw0ocU6ApNgqTVRZuSwjJAbhCcmweMq6RiVYEic/edit?usp=sharing)
1010
* [UML Diagram](https://drive.google.com/file/d/1FVrnYiuAR8ykqfOUa1NuoMyZ1abXzMPw/view?usp=drive_link)
1111

12+
## Running Tests
13+
14+
```bash
15+
uv sync # install dev deps (incl. pytest, pytest-cov)
16+
uv run pytest # full suite (skips network-marked tests if you add `-m "not network"`)
17+
uv run pytest tests/test_swe_components.py -v # one file, verbose
18+
uv run pytest -k name_token # one keyword
19+
```
20+
21+
Tests that need a live OSH server (e.g. `localhost:8282` running
22+
FakeWeatherDriver) are tagged `@pytest.mark.network`. CI skips them; locally
23+
you can include or exclude them:
24+
25+
```bash
26+
uv run pytest -m "not network" # what CI runs
27+
uv run pytest -m network # only the live-server tests
28+
```
29+
30+
## Test Coverage
31+
32+
Coverage is opt-in via [`pytest-cov`](https://pytest-cov.readthedocs.io/). The
33+
default `pytest` run is fast; add `--cov` when you want a report.
34+
35+
```bash
36+
uv run pytest --cov # terminal summary + missing lines
37+
uv run pytest --cov --cov-report=html # HTML report at htmlcov/index.html
38+
uv run pytest --cov --cov-report=xml # coverage.xml (CI / Codecov-ready)
39+
```
40+
41+
Configuration lives in `pyproject.toml` under `[tool.coverage.*]` — branch
42+
coverage is on, source is scoped to `src/oshconnect`, and obvious dead lines
43+
(`if TYPE_CHECKING:`, `raise NotImplementedError`, etc.) are excluded.
44+
45+
CI (`.github/workflows/tests.yaml`) runs the suite with `--cov` on every push
46+
across Python 3.12 / 3.13 / 3.14 and uploads `coverage.xml` as a workflow
47+
artifact (downloadable from the run page).
48+
49+
## Documentation Coverage
50+
51+
[`interrogate`](https://interrogate.readthedocs.io/) reports what fraction of
52+
public modules / classes / functions / methods carry a docstring (presence
53+
only, it doesn't check style). It's purely informational right now; there's
54+
no CI gate. Configuration lives in `pyproject.toml` under `[tool.interrogate]`
55+
(`__init__`, dunder, private, and property/setter members are skipped).
56+
57+
```bash
58+
uv run interrogate src/oshconnect # one-line summary
59+
uv run interrogate -v src/oshconnect # per-file table
60+
uv run interrogate -vv src/oshconnect # per-symbol (shows which symbols are missing)
61+
```
62+
63+
Once we agree on a baseline, raise `[tool.interrogate].fail-under` from `0` so
64+
new code without docstrings starts failing locally and in CI.
65+
1266
## Generating the Docs
1367

1468
The documentation is built with [MkDocs](https://www.mkdocs.org/) using the

pyproject.toml

Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,8 @@ dependencies = [
1919
dev = [
2020
"flake8>=7.2.0",
2121
"pytest>=8.3.5",
22+
"pytest-cov>=5.0.0",
23+
"interrogate>=1.7.0",
2224
"sphinx>=7.4.7",
2325
"sphinx-rtd-theme>=2.0.0",
2426
"mkdocs-material>=9.5.0",
@@ -34,3 +36,41 @@ pythonpath = ["src"]
3436
markers = [
3537
"network: test requires a live OSH server or external network endpoint (skipped by default in CI; see workflow `tests.yaml`).",
3638
]
39+
40+
# Coverage is opt-in (run with `pytest --cov`) so the default `pytest` run stays fast.
41+
# `--cov` with no argument picks up the source paths configured below.
42+
43+
[tool.coverage.run]
44+
source = ["src/oshconnect"]
45+
branch = true
46+
47+
[tool.coverage.report]
48+
show_missing = true
49+
skip_covered = false
50+
precision = 2
51+
exclude_lines = [
52+
"pragma: no cover",
53+
"raise NotImplementedError",
54+
"if TYPE_CHECKING:",
55+
"@(abc\\.)?abstractmethod",
56+
"if __name__ == .__main__.:",
57+
]
58+
59+
[tool.coverage.html]
60+
directory = "htmlcov"
61+
62+
[tool.coverage.xml]
63+
output = "coverage.xml"
64+
65+
# Docstring presence (not style). Run with `uv run interrogate -v src/oshconnect`.
66+
[tool.interrogate]
67+
ignore-init-method = true # constructors covered by class docstring
68+
ignore-init-module = true # don't require docstrings on bare __init__.py
69+
ignore-magic = true # skip dunder methods (__repr__, __eq__, etc.)
70+
ignore-private = true # skip _name and __name (non-dunder) members
71+
ignore-property-decorators = true
72+
ignore-nested-functions = true
73+
ignore-setters = true
74+
fail-under = 0 # report-only for now; raise once a baseline is set
75+
exclude = ["tests", "docs", "build", ".venv", "scripts"]
76+
verbose = 2 # 0=summary, 1=per-file, 2=per-symbol

0 commit comments

Comments
 (0)