docs: LDD baseline с mutation и browser E2E
This commit is contained in:
@@ -294,9 +294,10 @@ upgrade-тест миграций, видимость активов и deploy-r
|
||||
## 7. LDD baseline
|
||||
|
||||
После этапа 6 текущая функциональность проверена через LDD-контур:
|
||||
реестр `docs/evidence/claims.json` (31 claim, 19 P0 / 12 P1), gate
|
||||
`./gradlew evidenceCheck`, upgrade-скрипт и runtime-smoke полного стека.
|
||||
Результат: **31/31 claims proven, P0 gaps = 0**, 267 тестов, upgrade с
|
||||
master-схемы и E2E-поток «админ → группа → курс → преподаватель → лаба»
|
||||
проходят. Подробности и остаточные ограничения —
|
||||
реестр `docs/evidence/claims.json` (34 claim, 19 P0 / 15 P1), gate
|
||||
`./gradlew evidenceCheck`, upgrade-скрипт, runtime-smoke, mutation testing
|
||||
и браузерный Playwright E2E. Результат: **34/34 claims proven, P0 gaps = 0**,
|
||||
273 теста; mutation strength `CourseAccessService` 75%,
|
||||
`PromotionPlanner` 69%; browser E2E 3/3. E2E нашёл и закрыл реальный дефект
|
||||
Jackson 3/Kotlin defaults. Подробности и остаточные ограничения —
|
||||
[`docs/evidence/baseline-2026-10-27.md`](evidence/baseline-2026-10-27.md).
|
||||
|
||||
@@ -44,16 +44,27 @@
|
||||
|
||||
# 4. Проверка upgrade с master-схемы
|
||||
./scripts/ldd-migration-upgrade.sh
|
||||
|
||||
# 5. Mutation testing критичных P0-компонентов
|
||||
./scripts/ldd-mutation.sh
|
||||
|
||||
# 6. Браузерный E2E (Playwright + Chromium)
|
||||
./scripts/ldd-browser.sh
|
||||
```
|
||||
|
||||
Для E2E один раз установите зависимости: `cd e2e && npm install`.
|
||||
Mutation harness использует JUnit 4: JUnit5-плагин PIT несовместим с JUnit
|
||||
Platform 6 из Spring Boot 4.
|
||||
|
||||
Отчёт: `build/reports/evidence/index.md`.
|
||||
|
||||
## Правила
|
||||
|
||||
1. Новое P0-требование без свидетельства не мержится.
|
||||
2. Свидетельство должно быть воспроизводимым в CI, а не «проверил руками».
|
||||
3. Тест должен падать при поломке соответствующей логики; для критичных
|
||||
пакетов позже добавим mutation testing.
|
||||
3. Тест должен падать при поломке соответствующей логики. Для критичных
|
||||
пакетов это измеряется mutation testing: сейчас `CourseAccessService` —
|
||||
75% test strength, `PromotionPlanner` — 69%.
|
||||
4. Один тест может подтверждать несколько claims, но claim не должен
|
||||
опираться на тест, который проверяет только реализацию.
|
||||
5. `limitations` обязателен: LDD не должен создавать иллюзию полного
|
||||
@@ -65,12 +76,21 @@
|
||||
|
||||
## Текущий baseline
|
||||
|
||||
Первый прогон LDD выполнен 2026-10-27:
|
||||
Первый LDD-цикл выполнен 2026-10-27/28:
|
||||
|
||||
- 267 автоматических тестов, 0 failures/errors;
|
||||
- 33 claims: P0 — доступы, повышение, жизненный цикл, профиль/скачивание,
|
||||
материалы/активы, миграция V13, аудит; P1 — группы, авторство, UI,
|
||||
контракты, импорт, копирование лаб, runtime.
|
||||
- Runtime-smoke и master-upgrade вынесены в отдельные скрипты.
|
||||
- **273 автоматических теста**, 0 failures/errors;
|
||||
- **34 claims**: 19 P0 + 15 P1. P0 — доступы, повышение, жизненный цикл,
|
||||
профиль/скачивание, материалы/активы, миграция V13, аудит; P1 — группы,
|
||||
авторство, UI, контракты, импорт, копирование лаб, runtime, mutation и
|
||||
browser E2E;
|
||||
- mutation testing: `CourseAccessService` 75% test strength,
|
||||
`PromotionPlanner` 69%;
|
||||
- Playwright: 3 сценария (admin, teacher, student/anonymous), все зелёные;
|
||||
- runtime-smoke, master-upgrade, mutation и browser E2E вынесены в отдельные
|
||||
скрипты.
|
||||
|
||||
Результаты и найденные пробелы — в `baseline-2026-10-27.md`.
|
||||
В ходе E2E найден и исправлен реальный дефект: Jackson 3 не применял
|
||||
Kotlin-модуль, поэтому DTO с default-значениями требовали все поля JSON
|
||||
(например, создание студента без `firstName`/`basis` давало 400).
|
||||
|
||||
Результаты и остаточные ограничения — в `baseline-2026-10-27.md`.
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
# LDD baseline: 2026-10-27
|
||||
# LDD baseline: 2026-10-27/28
|
||||
|
||||
Первый прогон доказательной проверки текущей функциональности LMS.
|
||||
Код приложения в этом прогоне не менялся; добавлены реестр claims, gate
|
||||
`evidenceCheck`, runtime- и migration-скрипты.
|
||||
Первый и второй LDD-циклы проверки текущей функциональности LMS.
|
||||
Добавлены реестр claims, gate `evidenceCheck`, runtime/migration/mutation
|
||||
скрипты и браузерный E2E на Playwright. В ходе проверки найден и исправлен
|
||||
реальный дефект Jackson 3.
|
||||
|
||||
## 1. Что проверялось
|
||||
|
||||
Реестр: `docs/evidence/claims.json`, 31 утверждение.
|
||||
Реестр: `docs/evidence/claims.json`, **34 утверждения**.
|
||||
|
||||
| Критичность | Claims | Proven | Gaps |
|
||||
|---|---:|---:|---:|
|
||||
| P0 | 19 | 19 | 0 |
|
||||
| P1 | 12 | 12 | 0 |
|
||||
| **Итого** | **31** | **31** | **0** |
|
||||
| P1 | 15 | 15 | 0 |
|
||||
| **Итого** | **34** | **34** | **0** |
|
||||
|
||||
Домены:
|
||||
|
||||
@@ -24,8 +25,9 @@
|
||||
- материалы и активы;
|
||||
- миграция V13 и полный upgrade с master-схемы;
|
||||
- аудит: токен, admin-only, сохранность после удаления, representative-хуки;
|
||||
- группы курса, авторство материалов, ведомость, UI/контракты, импорт, копирование лаб;
|
||||
- runtime-smoke полного стека.
|
||||
- группы курса, авторство материалов, ведомость, UI/контракты, импорт,
|
||||
копирование лабораторных;
|
||||
- runtime-smoke, mutation testing, браузерный E2E.
|
||||
|
||||
## 2. Команды и результаты
|
||||
|
||||
@@ -35,7 +37,7 @@
|
||||
./gradlew test --rerun-tasks
|
||||
```
|
||||
|
||||
Результат: **267 тестов, 0 failures, 0 errors, 0 skipped**.
|
||||
Результат: **273 теста, 0 failures, 0 errors, 0 skipped**.
|
||||
`ktlintCheck` и `detekt` — зелёные.
|
||||
|
||||
### 2.2. LDD gate
|
||||
@@ -44,7 +46,7 @@
|
||||
./gradlew evidenceCheck
|
||||
```
|
||||
|
||||
Результат: **31/31 claims proven, P0 gaps = 0**.
|
||||
Результат: **34/34 claims proven, P0 gaps = 0**.
|
||||
Отчёт: `build/reports/evidence/index.md`.
|
||||
|
||||
Gate устроен так:
|
||||
@@ -94,49 +96,94 @@ identity `V4–V10`, academic `V6–V12`, progress `V13`.
|
||||
- чужой преподаватель получает `403` на курс, лабу и аудит;
|
||||
- админ видит audit-события `COURSE_CREATE`, `TEACHER_CREATE`,
|
||||
`COURSE_TEACHER_ASSIGN`, `COURSE_GROUP_ATTACH`, `LAB_CREATE`;
|
||||
- web `/login` отдаёт `200`, публичное дерево материалов доступно, курсовая
|
||||
- web `/login` отдаёт `200`, публичное дерево материалов доступно, курсовые
|
||||
материалы анонимно — `401`.
|
||||
|
||||
Результат: **PASS**, evidence: `build/evidence/runtime.json`.
|
||||
Стек и одноразовая БД после прогона остановлены/удалены.
|
||||
|
||||
### 2.5. Mutation testing
|
||||
|
||||
```bash
|
||||
./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
|
||||
|
||||
```bash
|
||||
./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-схемы и поднимается полным
|
||||
- Приложение собирается, мигрирует с master-схемы и поднимается полным
|
||||
стеком на чистой БД.
|
||||
- Ключевой доменный поток «админ → группа → курс → преподаватель → лаба»
|
||||
проходит через реальные HTTP/gateway/БД, а не только через mock.
|
||||
проходит через реальные HTTP/gateway/БД и браузер.
|
||||
- Чужой преподаватель не получает доступ к курсу/лабе/аудиту на реальном стеке.
|
||||
- Аудит пишется и читается; upgrade не теряет синтетические данные.
|
||||
- Мутационная прочность критичных компонентов измерена, а не заявлена.
|
||||
- Реальный дефект DTO/Jackson найден именно E2E-контуром и закрыт тестом.
|
||||
|
||||
## 4. Чего это не доказывает
|
||||
|
||||
1. **Нет браузерного E2E.** Thymeleaf-тесты проверяют HTML, но не реальные
|
||||
клики/JS/CSRF/редиректы в браузере.
|
||||
2. **Нет нагрузочных и конкурентных испытаний.** Advisory locks и гонки
|
||||
1. **Нет нагрузочных и конкурентных испытаний.** Advisory locks и гонки
|
||||
проверены кодом и unit/integration-тестами, но не под нагрузкой.
|
||||
3. **Нет mutation testing.** Сила тестов измерена косвенно; следующий шаг —
|
||||
PIT на `CourseAccessService`, `PromotionService`, `StudentProfileService`.
|
||||
4. **Нет property-based/model-based проверки повышения.** Один сценарный тест
|
||||
не покрывает все комбинации курсов, степеней и академ-переходов.
|
||||
2. **Mutation testing не 100%.** Остаются эквивалентные мутанты и
|
||||
Kotlin/Spring-специфичные мутации; PIT harness — JUnit 4, а не JUnit 5.
|
||||
3. **Property-based тесты покрывают не все ветки.** Есть генераторы для
|
||||
матрицы доступа и планировщика повышения, но не для транзакционного
|
||||
apply/rollback и конкурентных сценариев.
|
||||
4. **Браузерный E2E — один Chromium и один сценарий на роль.** Нет
|
||||
визуальной регрессии, мобильных размеров, Safari/Firefox.
|
||||
5. **Legacy-активы без `article_assets` остаются публичными.**
|
||||
6. **JWT живёт до 30 дней.** Web перепроверяет статус, прямой API — нет.
|
||||
7. **Ведущие нули номера группы нормализуются** (`01` → `1`).
|
||||
8. **Нет пагинации/keyset** для части списков и N+1 в отдельных экранах.
|
||||
9. **Runtime-smoke не входит в unit-CI**; он запускается отдельным скриптом
|
||||
перед релизом.
|
||||
9. **Runtime/mutation/browser E2E не входят в unit-CI**; это release-скрипты.
|
||||
|
||||
## 5. Вывод
|
||||
|
||||
Текущая функциональность прошла первый LDD-контур: **P0 gaps = 0**,
|
||||
полный стек и upgrade работают. Это достаточное основание продолжать
|
||||
доработки, но не «формальное доказательство всей системы». Следующий цикл
|
||||
LDD должен добавить:
|
||||
Текущая функциональность прошла LDD-контур: **34/34 claims proven, P0 gaps = 0**,
|
||||
273 теста, upgrade, mutation baseline и браузерный E2E зелёные. Это
|
||||
достаточное основание продолжать доработки, но не «формальное доказательство
|
||||
всей системы».
|
||||
|
||||
1. mutation testing для критичных пакетов;
|
||||
2. property-based тесты повышения и матрицы доступа;
|
||||
3. браузерный E2E (Playwright) для ведомости, профиля и материалов;
|
||||
4. нагрузочный smoke на чтение ведомости/профиля;
|
||||
5. автоматический runtime-smoke в release-пайплайне.
|
||||
Следующий цикл LDD:
|
||||
|
||||
1. нагрузочный smoke на чтение ведомости/профиля и конкурентный apply/rollback;
|
||||
2. property-based/model-based тесты транзакционного повышения;
|
||||
3. расширение browser E2E (студенческая сдача, публикация оценки, мобильный вид);
|
||||
4. автоматический release-пайплайн с runtime/mutation/browser evidence.
|
||||
|
||||
Reference in New Issue
Block a user