feat: pytest-cov configuration and test audit cleanup

Add full pytest-cov configuration with fail_under=60% threshold,
HTML/XML report targets, and proper exclude_lines. Fix websocket
history test to use public broadcast() API instead of manually
manipulating internals. Audit confirmed 491 tests at 71.2% coverage.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
Alexander Payne
2026-02-22 20:42:58 -05:00
parent 14072f9bb5
commit ca60483268
4 changed files with 41 additions and 11 deletions

1
.gitignore vendored
View File

@@ -27,6 +27,7 @@ telegram_state.json
# Testing
.pytest_cache/
.coverage
coverage.xml
htmlcov/
reports/

View File

@@ -1,4 +1,4 @@
.PHONY: install install-bigbrain dev test test-cov watch lint clean help \
.PHONY: install install-bigbrain dev test test-cov test-cov-html watch lint clean help \
docker-build docker-up docker-down docker-agent docker-logs docker-shell
VENV := .venv
@@ -57,6 +57,10 @@ test:
test-cov:
$(PYTEST) tests/ --cov=src --cov-report=term-missing --cov-report=xml -q
test-cov-html:
$(PYTEST) tests/ --cov=src --cov-report=term-missing --cov-report=html -q
@echo "✓ HTML coverage report: open htmlcov/index.html"
# ── Code quality ──────────────────────────────────────────────────────────────
lint:
@@ -105,8 +109,9 @@ help:
@echo " make install-bigbrain install with AirLLM (big-model backend)"
@echo " make dev start dashboard at http://localhost:8000"
@echo " make ip print local IP addresses for phone testing"
@echo " make test run all 228 tests"
@echo " make test-cov tests + coverage report"
@echo " make test run all tests"
@echo " make test-cov tests + coverage report (terminal + XML)"
@echo " make test-cov-html tests + HTML coverage report"
@echo " make watch self-TDD watchdog (60s poll)"
@echo " make lint run ruff or flake8"
@echo " make clean remove build artefacts and caches"

View File

@@ -83,4 +83,27 @@ addopts = "-v --tb=short"
[tool.coverage.run]
source = ["src"]
omit = ["*/tests/*"]
omit = [
"*/tests/*",
"src/dashboard/routes/mobile_test.py",
]
[tool.coverage.report]
show_missing = true
skip_empty = true
precision = 1
exclude_lines = [
"pragma: no cover",
"if __name__ == .__main__.",
"if TYPE_CHECKING:",
"raise NotImplementedError",
"@abstractmethod",
]
# Fail CI if coverage drops below this threshold
fail_under = 60
[tool.coverage.html]
directory = "htmlcov"
[tool.coverage.xml]
output = "coverage.xml"

View File

@@ -2,6 +2,8 @@
import json
import pytest
from websocket.handler import WebSocketManager, WSEvent
@@ -18,13 +20,12 @@ def test_ws_manager_initial_state():
assert mgr.event_history == []
def test_ws_manager_event_history_limit():
@pytest.mark.asyncio
async def test_ws_manager_event_history_limit():
"""History is trimmed to max_history after broadcasts."""
mgr = WebSocketManager()
mgr._max_history = 5
for i in range(10):
event = WSEvent(event=f"e{i}", data={}, timestamp="t")
mgr._event_history.append(event)
# Simulate the trim that happens in broadcast
if len(mgr._event_history) > mgr._max_history:
mgr._event_history = mgr._event_history[-mgr._max_history:]
assert len(mgr._event_history) == 5
await mgr.broadcast(f"e{i}", {})
assert len(mgr.event_history) == 5
assert mgr.event_history[0].event == "e5"