12 KiB
CODE-REVIEW-630-r1
Issue: #630 — tests_backend/conftest.py: без HA 277 (сейчас 292) тестов test_ha_*.py
не собираются молча (collect_ignore_glob) — печатать явное предупреждение.
Материал: origin/dev...HEAD, вершина 51e1643762917f362fba14ffc3559766f173a484,
один коммит. Трек trivial (S2 → S5, минуя ТЗ), лимит циклов код-ревью — 2 (§5.1).
Заход: r1 · блокирующих циклов израсходовано 0 из 2.
Скоуп диффа
AGENTS.md
docs/TESTING.md
scripts/mutation-registry.mjs
tests_backend/conftest.py
tests_backend/test_conftest_harness_notice.py (новый)
Инфраструктура тестов, custom_components/** и src/** не тронуты. Это не
продуктовая фича и не обязано закрывать строку Core user jobs (docs/SCOPE.md) —
это гейт качества самого процесса разработки (класс, аналогичный записям
"Backend quality gates" в docs/ARCHITECTURE.md §"#42"). User-Visible: no
в трейлере коммита соответствует действительности — правки в
docs/changelog/не требуются и не сделаны, это корректно.
Что сделано (по коммиту 51e16437)
tests_backend/conftest.py: без HA, при импорте модуля,ha_harness_inventory()однократно считает файлыtest_ha_*.pyтем же glob, что иcollect_ignore_glob, и объявленияdef test_*/async def test_*(включая методы классов) регулярным выражением. Результат печатается дважды —pytest_report_header(полный прогон) иpytest_terminal_summary(не зависит от-q, печатается всегда).tests_backend/test_conftest_harness_notice.py— новый чистый тест: обе ветки conftest (HA есть / нет) проверяются сборкой временного мини-проекта во вложенном процессе pytest,homeassistantподменён заглушкой наPYTHONPATH.docs/TESTING.md,AGENTS.md— формулировка «silently skips» заменена точной («does not collect» / «не собирается вовсе»), с указанием механизма (collect_ignore_glob) и ссылкой на #630.scripts/mutation-registry.mjs— два новых мутанта:ha-harness-notice-silent(гаситterminal_summary),ha-harness-notice-count-frozen(замораживает число тестов на 292).
Как проверялось (исполнением, не только чтением)
Зелёный Validate на 51e16437 (https://github.com/Matysh/houseplan-card/actions/runs/35942627518)
покрывает frontend (tsc, npm test, npm run build) и backend-job CI с
установленным HA — это НЕ тот путь, который меняет диф (AC1 — про среду
БЕЗ HA). Поэтому именно этот путь прогнан здесь заново, вручную, а не принят
на слово:
pip3 install --user pytest voluptuous— в песочнице ревью изначально не было ни pytest, ни voluptuous ни для одного бэкенд-теста; это окружение ближе к «Windows/песочница» из тела issue, чем CI.python3 -m pytest tests_backend -q -p no:cacheprovider(без HA, реальный харнесс, не временный) →485 passed, 4 skipped, 1 warning, и в конце секция:HA harness not collected/HA harness NOT collected: 13 test_ha_*.py files (292 tests) were ignored…. Число совпало с независимым пересчётом тем же регэкспом вручную (13 файлов, 292 теста) — AC1 подтверждён живым прогоном, включая формулировку в-q.python3 -m pytest tests_backend/test_conftest_harness_notice.py -q -p no:cacheprovider→5 passed. Новый тест реально существует и реально зелёный, не только назван в отчёте автора.node scripts/mutation-gate.mjs --id=ha-harness-notice-silent→поймано 1 из 1.node scripts/mutation-gate.mjs --id=ha-harness-notice-count-frozen→поймано 1 из 1. Проверена дисциплина «тест умеет падать»: без этих двух правок вconftest.pyтест из п.3 действительно краснеет (мутация применяется, гоняется, откатывается —git statusпосле чист).node scripts/mutation-gate.mjs --check— все якоря реестра, включая два новых, находятся (ok ha-harness-notice-silent,ok ha-harness-notice-count-frozen), полный реестр не сломан.- Проверено отдельно (не входит в отчёт автора, но релевантно диффу): CI-шаг
«HA-harness присутствует» (
validate.yml:1185-1190) считаетgrep -c "test_ha_"по выводу--collect-onlyи требует≥50. Новыйpytest_report_header/terminal_summaryпечатает строку, содержащуюtest_ha_*.py, только когдаHAS_HAложно — в CIHAS_HAистинно (шаг до этого явно делаетpython -c "import homeassistant"), значитHA_HARNESS_IGNORED is Noneи хуки возвращаютNone/no-op. Порог≥50не задет. Регрессии в существующем CI-гейте нет. - Проверено чтением, не исполнением: реального HA-харнесса под Linux CI/WSL
здесь нет (как и у автора) — ветка
HAS_HAв диффе не меняется, только вынесен общийfrom pathlib import Pathнаверх файла (было продублировано в обеих веткахif not HAS_HA/if HAS_HA); синтаксической ошибки в этом рефакторинге нет — файл успешно импортируется и исполняется в п.2 и п.3. - Прочитан diff
docs/TESTING.md/AGENTS.md: формулировка исправлена на точную во всех местах, которые называет AC2.CLAUDE.mdрабочей папки вне репозитория и вне материала ревью — принимается на слово автора, как и заявлено самим автором в разделе «Чего не проверял».
Чего не проверял (осознанно, гейт не по размеру задачи)
npx tsc --noEmit, полныйnpm test,npm run build— diff не трогаетsrc/**ни один файл; Validate на этом SHA уже зелёный и покрывает их.node scripts/check-docs.mjs— не запускался: скрипт применим при правкахsrc/**, диф их не трогает.- Инварианты модели (
npm run invariants) — diff не трогает геометрию, рёбра комнат,layout,marker.space,open_spans. - Браузерные
demo/smoke_*.mjsиnpm run golden:verify— диф не меняет ни один рендер-путь;scripts/smoke-select.mjsне запускался осознанно, так как изменения не в JS/TS рантайме карточки, а в Python-тест-харнессе и markdown; смоки физически не видятtests_backend/. - Настоящий HA-харнесс на Linux CI/WSL — здесь нет HA (как и у автора); ветка
HAS_HAне менялась, поэтому риск сочтён низким и не гейтится вручную — сама CI job "Бэкенд: pytest в Home Assistant" прогонит это на слиянии. - ruff/mypy по
custom_components/houseplan/**— диф их не касается. - Windows-прогон — недоступен в песочнице; код использует только
pathlib,sys.executable, декодирование с `errors="replace"", риск сочтён низким.
Находки
Нет находок уровня High или Medium в скоупе. Одно наблюдение, не требующее действия (Low, не в скоупе AC2):
docs/ARCHITECTURE.md:2124всё ещё говорит «refuses to run when the HA harness would silently skip» — та же неточная формулировка про этот же механизм (collect_ignore_glob), но AC2 issue #630 явно ограничивает объём правкиdocs/TESTING.mdи локальнымCLAUDE.md;ARCHITECTURE.mdв тексте issue не назван. Не блокирует: формулировка описывает CI-гейт (порог≥50), а не поведение локального pytest, которое и было предметом задачи; контекст не вводит читателя в заблуждение так же остро, как исправленные места. Снимается без действия — правка по желанию в отдельной задаче, не заводится отдельным issue (Low, §12 — либо правится в скоупе, либо снимается с записью; здесь скоуп задачи её не включает).
Итог по AC
| AC | Статус | Доказательство |
|---|---|---|
| AC1: вывод pytest без HA явно называет число несобранных HA-файлов/тестов | Выполнено | Живой прогон pytest tests_backend -q в песочнице ревью (не только отчёт автора): секция HA harness not collected с 13 files (292 tests), само число сошлось с независимым пересчётом |
| AC1: число не зашито, следует за харнессом | Выполнено | test_inventory_of_the_real_harness_matches_an_independent_count (AST) зелёный; мутант ha-harness-notice-count-frozen пойман 1/1 |
AC2: формулировка «скипает» исправлена в docs/TESTING.md/AGENTS.md |
Выполнено | Дифф прочитан, старая формулировка не встречается в этих файлах |
AC2: CLAUDE.md рабочей папки |
Не в материале ревью (вне репозитория) | Принято на слово автора, как заявлено самим автором |
Вердикт
Зелёный. AC доказаны исполнением, не только заявлением автора; мутанты
проверены на способность падать; регрессии в существующем CI-пороге ≥50
не обнаружено. Единственное наблюдение — Low, вне скоупа AC2, снимается без
действия.
Материал раунда
- Ветка:
issue/630-ha-harness-warning, коммит51e164376291— ребейз его осиротит, и это нормально: ниже якоря, которые ребейз не меняет. - Дерево материала:
3b1a904c469fc9c81d14f6e35d0f80c74af7abdbgit log --all --format='%H %T' | grep 3b1a904c469f - Тело issue:
f68ed5ca3ddef44a1f638bcb046751e5e3b0f92df99ef272ade03444ccd2cb63 - Вердикт конвейера:
green· High 0