Skip to main content

tdd

HelmLog-specific test patterns and the pre-existing-error allowlist for ruff/mypy. The Red-Green-Refactor cycle and lint commands are already mandated in CLAUDE.md — this skill encodes only the patterns and known-pre-existing-errors list that aren't recoverable from existing tests at a glance. TRIGGER when writing or modifying Python source code in src/helmlog/. DO NOT trigger for documentation, config, templates, CSS/JS, skill definitions, or changes that don't affect runtime behavior.

설치로 이동

소스 정보

저장소
weaties/helmlog
최근 소스 활동
2026년 6월 4일 19:29
감지된 SKILL.md 언어
영어
스타
2
포크
2

설치 방법

기본적으로 소스를 먼저 확인하는 Prompt가 선택됩니다. 직접 명령으로 전환하거나 로컬 사본을 다운로드할 수도 있습니다.

소스 파일 검토

설치 여부를 결정하기 전에 SKILL.md와 SkillsMP에 표시된 보조 파일을 읽어 보세요.

파일 탐색기
2 개 파일

SKILL.md 표시 중

SKILL.md
소스 지침 · 읽기 전용 미리보기
name
tdd
description
HelmLog-specific test patterns and the pre-existing-error allowlist for ruff/mypy. The Red-Green-Refactor cycle and lint commands are already mandated in CLAUDE.md — this skill encodes only the patterns and known-pre-existing-errors list that aren't recoverable from existing tests at a glance. TRIGGER when writing or modifying Python source code in src/helmlog/. DO NOT trigger for documentation, config, templates, CSS/JS, skill definitions, or changes that don't affect runtime behavior.
# TDD — HelmLog patterns CLAUDE.md already mandates: failing test → implement → green → lint. This skill encodes only the project-specific bits that aren't obvious from existing tests: ## Test patterns **Storage tests** — use the shared `storage` fixture from `conftest.py` (in-memory SQLite, fully migrated; never construct `Storage` by hand in a test): ```python @pytest.mark.asyncio async def test_my_feature(storage: Storage) -> None: # storage is ready with all migrations applied ... ``` **Web route tests** — use `httpx.AsyncClient` with `ASGITransport`, not the sync `TestClient`: ```python @pytest.mark.asyncio async def test_my_endpoint(storage: Storage) -> None: from helmlog.web import create_app app = create_app(storage) async with httpx.AsyncClient( transport=ASGITransport(app=app), base_url="http://test" ) as client: resp = await client.get("/api/my-endpoint") assert resp.status_code == 200 ``` **Hardware mocking** — patch hardware modules at the import site so the test never touches real devices: ```python with patch("helmlog.cameras.httpx.AsyncClient") as mock_client: ... ``` Hardware modules to mock: `audio.py`, `can_reader.py`, `sk_reader.py`, `cameras.py`. ## Don't rationalize skipping the cycle The cycle only helps if you don't talk yourself out of it. Common excuses and their rebuttals: | Rationalization | Rebuttal | |---|---| | "This change is too small to need a test." | Size predicts neither breakage nor regression. A failing test first is what proves the change does what you think — write it. | | "I'll write the test after I see it work." | Test-after rationalizes whatever the code already does, bugs included. Red-Green-Refactor is mandated in CLAUDE.md for a reason. | | "It's just a renderer/route tweak — I'll eyeball it." | Web routes are the easiest place to ship a silent 500. Use the `AsyncClient`/`ASGITransport` pattern above. | | "Tests pass, so it's correct." | Passing tests are evidence, not proof. Confirm the test exercises the new behavior and would actually fail without your change. | | "ruff/mypy is noisy here, I'll skip the lint gate." | Only the pre-existing-error allowlist below is exempt. Everything else is green-before-PR. | ## Pre-existing errors to ignore Do not fix these unless explicitly asked — they are tracked separately: - `web.py`: `Item "None" of "datetime | None" has no attribute "isoformat"` - `web.py`: `Item "None" of "AudioRecorder | None" has no attribute "stop"` (×2) - `main.py`: `Unused "type: ignore" comment` - `storage.py`: 2 pre-existing E501 line-length violations
GitHub에서 보기