9.7 KiB
LDD baseline: 2026-10-27/28
Первый и второй LDD-циклы проверки текущей функциональности LMS.
Добавлены реестр claims, gate evidenceCheck, runtime/migration/mutation
скрипты и браузерный E2E на Playwright. В ходе проверки найден и исправлен
реальный дефект Jackson 3.
1. Что проверялось
Реестр: docs/evidence/claims.json, 34 утверждения.
| Критичность | Claims | Proven | Gaps |
|---|---|---|---|
| P0 | 19 | 19 | 0 |
| P1 | 15 | 15 | 0 |
| Итого | 34 | 34 | 0 |
Домены:
- доступы: аноним/студент/преподаватель/админ, чужие курс/лаба/студент/группа, внутренние API identity;
- повышение: dry-run, apply, идемпотентность, rollback, cancel;
- жизненный цикл: академ, возврат, отчисление, архив, восстановление, вход;
- профиль студента и скачивание сдач;
- материалы и активы;
- миграция V13 и полный upgrade с master-схемы;
- аудит: токен, admin-only, сохранность после удаления, representative-хуки;
- группы курса, авторство материалов, ведомость, UI/контракты, импорт, копирование лабораторных;
- runtime-smoke, mutation testing, браузерный E2E.
2. Команды и результаты
2.1. Автоматические тесты
./gradlew test --rerun-tasks
Результат: 273 теста, 0 failures, 0 errors, 0 skipped.
ktlintCheck и detekt — зелёные.
2.2. LDD gate
./gradlew evidenceCheck
Результат: 34/34 claims proven, P0 gaps = 0.
Отчёт: build/reports/evidence/index.md.
Gate устроен так:
- каждый claim ссылается на конкретный JUnit-тест
Class#method; - P0 без зелёного теста валит сборку;
- P1-пробел показывается в отчёте;
- runtime-проверки читаются из
build/evidence/*.jsonи тоже должны бытьpassed, если claim на них ссылается.
2.3. Upgrade с master-схемы
./scripts/ldd-migration-upgrade.sh
Сценарий: одноразовая PostgreSQL 18, master identity V1–V3, academic
V1–V5, progress V1–V9,V11,V12, синтетические данные, затем ветка:
identity V4–V10, academic V6–V12, progress V13.
Проверено:
identity.audit_eventsсоздана;students,groups,membership_historyсохранились;labs.course_id,chapters.course_id,article_assetsсозданы;grade_comments.author_account_id,lab_grades.updated_by_account_idсозданы;- оценки и комментарии сохранились;
- повторное применение
V13идемпотентно.
Результат: PASS, evidence: build/evidence/migration.json.
2.4. Runtime-smoke полного стека
./scripts/ldd-runtime.sh
Сценарий: одноразовая БД, bootJar, запуск identity/academic/progress/gateway/web,
реальные HTTP-вызовы через gateway.
Проверено:
- health всех пяти сервисов =
UP; adminExists=falseдо setup, создание админа,/auth/me=ADMIN;- создание группы, курса, преподавателя, привязка группы, создание лабы;
- преподаватель входит и видит свой курс, лабу и состав группы;
- чужой преподаватель получает
403на курс, лабу и аудит; - админ видит audit-события
COURSE_CREATE,TEACHER_CREATE,COURSE_TEACHER_ASSIGN,COURSE_GROUP_ATTACH,LAB_CREATE; - web
/loginотдаёт200, публичное дерево материалов доступно, курсовые материалы анонимно —401.
Результат: PASS, evidence: build/evidence/runtime.json.
2.5. Mutation testing
./scripts/ldd-mutation.sh
PIT запускается через CLI с JUnit 4 harness: JUnit5-плагин PIT несовместим с JUnit Platform 6 из Spring Boot 4.
| Компонент | Мутаций | Убито | Test strength | Порог |
|---|---|---|---|---|
CourseAccessService |
56 | 42 | 75% | 70% |
PromotionPlanner |
162 | 109 | 69% | 60% |
Результат: PASS, evidence: build/evidence/mutation.json.
Остаток — эквивалентные мутации, Kotlin-интринсики и ветки, не входящие в
текущий P0-контур.
2.6. Браузерный E2E
./scripts/ldd-browser.sh
Playwright/Chromium на полном стеке, одноразовая БД:
- admin: вход,
/admin/coursesс курсом,/admin/auditс событием; - teacher: вход, курс, ведомость (группа/студент, без админских кнопок), профиль студента, создание главы курса;
- anonymous:
/admin/audit→/login; - student: вход,
/admin/audit→/student,/learn/course/{no}.
Результат: 3/3 passed, evidence: build/evidence/browser.json.
2.7. Найденный дефект
Первый browser E2E упал на создании студента: API вернул 400, потому что
Jackson 3 не применял Kotlin-модуль, и DTO с default-значениями требовали все
поля JSON. Исправлено: jackson-module-kotlin для Jackson 3 +
JsonMapperBuilderCustomizer в identity/academic/progress/web. Добавлен
регрессионный тест TeacherIntegrationTest.student creation accepts omitted optional json fields.
3. Что это доказывает
- Критичные P0-инварианты доступа, повышения, жизненного цикла, профиля, материалов, миграции и аудита имеют зелёные автоматические свидетельства.
- Приложение собирается, мигрирует с master-схемы и поднимается полным стеком на чистой БД.
- Ключевой доменный поток «админ → группа → курс → преподаватель → лаба» проходит через реальные HTTP/gateway/БД и браузер.
- Чужой преподаватель не получает доступ к курсу/лабе/аудиту на реальном стеке.
- Аудит пишется и читается; upgrade не теряет синтетические данные.
- Мутационная прочность критичных компонентов измерена, а не заявлена.
- Реальный дефект DTO/Jackson найден именно E2E-контуром и закрыт тестом.
4. Чего это не доказывает
- Нет нагрузочных и конкурентных испытаний. Advisory locks и гонки проверены кодом и unit/integration-тестами, но не под нагрузкой.
- Mutation testing не 100%. Остаются эквивалентные мутанты и Kotlin/Spring-специфичные мутации; PIT harness — JUnit 4, а не JUnit 5.
- Property-based тесты покрывают не все ветки. Есть генераторы для матрицы доступа и планировщика повышения, но не для транзакционного apply/rollback и конкурентных сценариев.
- Браузерный E2E — один Chromium и один сценарий на роль. Нет визуальной регрессии, мобильных размеров, Safari/Firefox.
- Legacy-активы без
article_assetsостаются публичными. - JWT живёт до 30 дней. Web перепроверяет статус, прямой API — нет.
- Ведущие нули номера группы нормализуются (
01→1). - Нет пагинации/keyset для части списков и N+1 в отдельных экранах.
- Runtime/mutation/browser E2E не входят в unit-CI; это release-скрипты.
5. Вывод
Текущая функциональность прошла LDD-контур: 34/34 claims proven, P0 gaps = 0, 273 теста, upgrade, mutation baseline и браузерный E2E зелёные. Это достаточное основание продолжать доработки, но не «формальное доказательство всей системы».
Следующий цикл LDD:
- нагрузочный smoke на чтение ведомости/профиля и конкурентный apply/rollback;
- property-based/model-based тесты транзакционного повышения;
- расширение browser E2E (студенческая сдача, публикация оценки, мобильный вид);
- автоматический release-пайплайн с runtime/mutation/browser evidence.