Files
LMS/docs/evidence/README.md

118 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# LDD: доказательное тестирование
Этот каталог — реестр утверждений о системе и свидетельств того, что они
выполняются. LDD здесь означает не «тесты вместо требований», а
**риск-ориентированную проверку**: требование → проверяемое утверждение →
независимый оракул → воспроизводимое свидетельство → допуск.
## Уровни
- **P0** — утверждение о безопасности, сохранности данных, доступах или
ключевом доменном правиле. P0 без зелёного свидетельства валит
`./gradlew evidenceCheck`.
- **P1** — важное поведение/UX/контракт. Пробел показывается в отчёте, но не
блокирует сборку.
- **runtime** — проверка на реально поднятом стеке. Быстрый smoke
(`scripts/ldd-smoke.sh`) выполняется в CI на каждом push/MR; полный
runtime/scale — в workflow `release` и обязателен перед релизом.
## Реестр
`claims.json` содержит:
- `id` — стабильный идентификатор (`LDD-ACCESS-001`);
- `title` — короткая формулировка;
- `criticality` — `P0`/`P1`;
- `status` — `active` или `gap`;
- `requirement` — ссылка на ТЗ/отчёт;
- `claim` — проверяемое утверждение (что именно истинно);
- `oracle` — как это проверяется;
- `evidence` — список `fully.qualified.Class#test name()` из JUnit XML;
- `runtime` — идентификаторы проверок из `build/evidence/runtime.json`;
- `limitations` — что утверждение **не** покрывает.
## Запуск
```bash
# 1. Все тесты и линтеры
./gradlew test ktlintCheck detekt
# 2. Гейт свидетельств (P0 без evidence = fail)
./gradlew evidenceCheck
# 3. Быстрый smoke полного стека (то же, что workflow smoke)
./scripts/ldd-smoke.sh
# 4. Полный runtime-smoke + scale load на одноразовой БД
./scripts/ldd-runtime.sh
# 5. Проверка upgrade с master-схемы
./scripts/ldd-migration-upgrade.sh
# 6. Mutation testing критичных P0-компонентов
./scripts/ldd-mutation.sh
# 7. Браузерный E2E (Playwright: Chromium/Firefox/WebKit)
./scripts/ldd-browser.sh
# 8. Полный release gate
./scripts/ldd-release.sh
```
Для E2E один раз установите зависимости и браузеры: `cd e2e && npm install && npx playwright install chromium firefox webkit`.
Mutation harness использует JUnit 4: JUnit5-плагин PIT несовместим с JUnit
Platform 6 из Spring Boot 4.
Отчёт: `build/reports/evidence/index.md`.
## Правила
1. Новое P0-требование без свидетельства не мержится.
2. Свидетельство должно быть воспроизводимым в CI, а не «проверил руками».
3. Тест должен падать при поломке соответствующей логики. Для критичных
пакетов это измеряется mutation testing: сейчас `CourseAccessService` —
75% test strength, `PromotionPlanner` — 69%.
4. Один тест может подтверждать несколько claims, но claim не должен
опираться на тест, который проверяет только реализацию.
5. `limitations` обязателен: LDD не должен создавать иллюзию полного
доказательства.
6. При переименовании теста обновляется `claims.json`; устаревшая ссылка —
это gap, а не «забыли».
7. Runtime-свидетельства обязательны перед релизом; CI на каждом push/MR
выполняет unit/integration-слой и быстрый smoke, полный release gate —
для тегов (вручную для веток).
## Текущий baseline
LDD-циклы выполнены 2026-10-27/28; последний — после закрытия продуктовых
рисков:
- **348 автоматических тестов**, 0 failures/errors;
- **51 claims**: 25 P0 + 26 P1, **51/51 proven, P0 gaps = 0**. P0 — доступы,
повышение, жизненный цикл, профиль/скачивание, материалы/активы
(включая secure-by-default legacy-файлы), миграции V11–V13, аудит,
refresh-токены и их отзыв; P1 — группы, авторство, UI, контракты, импорт,
копирование лаб, keyset-пагинация, пакетные детали лабораторных,
абсолютный потолок сессии, runtime, mutation и browser E2E;
- mutation testing: `CourseAccessService` 75% test strength,
`PromotionPlanner` 69%;
- Playwright: 6 сценариев (admin, teacher, student/anonymous, сдача+mobile,
cursor-аудит, инвентаризация активов) × Chromium/Firefox/WebKit = **18/18**,
все зелёные;
- масштабный load: 100 групп / 1000 студентов, 125 параллельных чтений,
0 ошибок, p95 < 1 с (порог p95 < 2 с);
- CI: Gitea + Woodpecker, workflow `smoke` (`ldd-smoke.sh`) на каждом push/MR;
полный `release` (`ldd-release.sh`) обязателен для тегов и ручной для веток.
Установка — `deploy/WOODPECKER.md`.
В ходе E2E найден и исправлен реальный дефект: Jackson 3 не применял
Kotlin-модуль, поэтому DTO с default-значениями требовали все поля JSON
(например, создание студента без `firstName`/`basis` давало 400).
Остаточные ограничения: ручная инвентаризация legacy-активов на production,
сдачи по выбранной лабораторной в ведомости, непроверенный первый CI-прогон на
реальных runner'ах и отсутствие визуальной регрессии. Legacy-активы, срок
access-токена, пагинация, N+1 деталей лабораторных, абсолютный лимит сессии и
«ведущие нули» больше не являются открытыми рисками.
Результаты — в `baseline-2026-10-27.md`.