Files
LMS/docs/evidence

LDD: доказательное тестирование

Этот каталог — реестр утверждений о системе и свидетельств того, что они выполняются. LDD здесь означает не «тесты вместо требований», а риск-ориентированную проверку: требование → проверяемое утверждение → независимый оракул → воспроизводимое свидетельство → допуск.

Уровни

  • P0 — утверждение о безопасности, сохранности данных, доступах или ключевом доменном правиле. P0 без зелёного свидетельства валит ./gradlew evidenceCheck.
  • P1 — важное поведение/UX/контракт. Пробел показывается в отчёте, но не блокирует сборку.
  • runtime — проверка на реально поднятом стеке. Быстрый smoke (scripts/ldd-smoke.sh) выполняется в CI на каждом push/MR; полный runtime/scale — в release-evidence и обязателен перед релизом.

Реестр

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 — что утверждение не покрывает.

Запуск

# 1. Все тесты и линтеры
./gradlew test ktlintCheck detekt

# 2. Гейт свидетельств (P0 без evidence = fail)
./gradlew evidenceCheck

# 3. Быстрый smoke полного стека (то же, что CI job 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)
./scripts/ldd-browser.sh

# 8. Полный release gate
./scripts/ldd-release.sh

Для E2E один раз установите зависимости и браузер: cd e2e && npm install && npx playwright install chromium. 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; последний — после закрытия продуктовых рисков:

  • 319 автоматических тестов, 0 failures/errors;
  • 46 claims: 25 P0 + 21 P1, 46/46 proven, P0 gaps = 0. P0 — доступы, повышение, жизненный цикл, профиль/скачивание, материалы/активы (включая secure-by-default legacy-файлы), миграция V13, аудит, refresh-токены и их отзыв; P1 — группы, авторство, UI, контракты, импорт, копирование лаб, пагинация аудита, bulk-группы курса, runtime, mutation и browser E2E;
  • mutation testing: CourseAccessService 75% test strength, PromotionPlanner 69%;
  • Playwright: 4 сценария (admin, teacher, student/anonymous, сдача+mobile), все зелёные;
  • масштабный load: 100 групп / 1000 студентов, 125 параллельных чтений, 0 ошибок, p95 < 1 с (порог p95 < 2 с);
  • CI: job smoke (ldd-smoke.sh) на каждом push/MR; полный release-evidence (ldd-release.sh) обязателен для тегов и ручной для веток.

В ходе E2E найден и исправлен реальный дефект: Jackson 3 не применял Kotlin-модуль, поэтому DTO с default-значениями требовали все поля JSON (например, создание студента без firstName/basis давало 400).

Остаточные ограничения: offset-пагинация аудита, N+1 в отдельных лабораторных списках/ведомости, отсутствие абсолютного лимита web-сессии. Legacy-активы, срок жизни JWT и «ведущие нули» больше не являются открытыми рисками. Результаты — в baseline-2026-10-27.md.