1 changed files with 363 additions and 252 deletions
@ -1,301 +1,412 @@
|
||||
# Инструкция для тестировщика: версионирование тестов и AI-функции |
||||
# Инструкция для тестировщика: версионирование тестов и AI |
||||
|
||||
> Контур: новый Flask на `:3108` (после E1.0–E1.3, E1.8). Старый Node — на `:3107`, |
||||
> для проверки этих задач **используйте только `:3108`**. |
||||
Сайт: **[https://edullm.pirogov.ai/](https://edullm.pirogov.ai/)** |
||||
|
||||
Перед началом: |
||||
Учётка: войдите под автором (роль «менеджер» или «администратор»). Если |
||||
учётки нет — попросите её у разработчика, без неё тестировать нельзя. |
||||
|
||||
1. Откройте `http://<host>:3108/login` под учёткой автора (роль `manager` или |
||||
`admin`). Если сидов нет — заведите пользователя в `clinic_tests.users` |
||||
обычным способом. |
||||
2. Для AI-задач: откройте `http://<host>:3108/settings` и убедитесь, что |
||||
статус ключа = «Задан» и кнопка **«Проверить подключение»** возвращает |
||||
зелёный **OK · provider/model · NN мс**. Если ключ не задан — AI-задачи |
||||
нужно прогнать в негативном сценарии (см. блок A.0). |
||||
3. Откройте `http://<host>:3108/tests` — это каталог. |
||||
> Всё, что описано ниже, проверяется **только через сайт**. Если в каком-то |
||||
> сценарии написано «недоступно сейчас» — это **не баг**, это значит, что |
||||
> функция UI ещё не сделана и появится позже. Просто пропускайте. |
||||
|
||||
--- |
||||
|
||||
## Часть 1. Версионирование при правке после попыток |
||||
|
||||
### Что должно работать |
||||
|
||||
| Правило | Поведение | |
||||
|---|---| |
||||
| Нет попыток | Автор правит тест **на месте**, номер версии не меняется. | |
||||
| Есть ≥ 1 попытка | Любое сохранение изменений **создаёт новую версию** (`version + 1`), старая становится неактивной, но **сохраняется в БД** и связана через `parent_id`. | |
||||
| Цепочка | Все версии связаны (parent → child), на странице «Версии» видны все. | |
||||
| Каталог | В списке видна **только активная** версия цепочки. | |
||||
| Переключение активной версии | Автор может вручную сделать активной любую версию — остальные автоматически становятся неактивными. | |
||||
| Деактивация цепочки | Тест можно скрыть целиком; данные не удаляются. | |
||||
| Корректность истории | Каждая попытка привязана к **той версии**, по которой её проходили — разбор ошибок остаётся корректным после правок. | |
||||
|
||||
### Сценарий 1.1. Правка теста до попыток (версия не растёт) |
||||
|
||||
1. В каталоге → **«Создать тест»**, заполните название и описание → создать. |
||||
2. В редакторе добавьте 2–3 вопроса по 3–4 варианта, сохраните. |
||||
3. Откройте этот же тест в редакторе ещё раз, измените: |
||||
- название; |
||||
- описание; |
||||
- текст одного вопроса; |
||||
- пометьте один вариант как правильный иначе; |
||||
- удалите/добавьте вариант. |
||||
4. **«Сохранить»**. |
||||
|
||||
**Ожидается:** |
||||
- Сообщение «Сохранено.» (без слов «создана новая версия»). |
||||
- В БД: `SELECT version FROM test_versions WHERE test_id = '<id>'` → **одна** строка с `version = 1, is_active = true`. |
||||
- Эндпоинт `GET /api/tests/<id>/versions` → массив из 1 элемента, `hasAttempts: false`. |
||||
|
||||
### Сценарий 1.2. Появление первой попытки → форк новой версии |
||||
|
||||
> Прохождение теста (UI) пока не реализовано в Flask-контуре (запланировано |
||||
> в **E1.4**). Поэтому факт попытки имитируется напрямую в БД — это норма |
||||
> для текущего этапа. |
||||
|
||||
1. Возьмите `id` теста и `id` активной версии: |
||||
```sql |
||||
SELECT t.id AS test_id, tv.id AS version_id |
||||
FROM tests t JOIN test_versions tv ON tv.test_id = t.id AND tv.is_active |
||||
WHERE t.title = 'Ваш тест'; |
||||
``` |
||||
2. Создайте «попытку» (минимальный INSERT, любой пользователь, любое |
||||
состояние; нам нужен только сам факт записи в `test_attempts`): |
||||
```sql |
||||
INSERT INTO test_attempts (id, test_version_id, user_id, status, created_at) |
||||
VALUES (gen_random_uuid(), '<version_id>', '<any_user_id>', 'completed', now()); |
||||
``` |
||||
3. В UI откройте редактор того же теста, **измените хотя бы один вопрос** |
||||
(текст / правильность варианта / число вариантов) и **«Сохранить»**. |
||||
|
||||
**Ожидается:** |
||||
- Сообщение «Сохранено (создана новая версия — есть попытки прохождения).» |
||||
- В БД: `SELECT version, is_active, parent_id FROM test_versions WHERE test_id=...` |
||||
→ **две** строки: |
||||
- `version = 1, is_active = false, parent_id = NULL` (старая, не удалена); |
||||
- `version = 2, is_active = true, parent_id = <id версии 1>` (новая). |
||||
- Старая попытка по-прежнему ссылается на `version_id` из v1, и её ответы/вопросы остаются те же — разбор ошибок не «съехал». |
||||
|
||||
### Сценарий 1.3. Правка только метаданных после попыток (без форка) |
||||
|
||||
После сценария 1.2: |
||||
|
||||
1. В редакторе **не трогайте** вопросы и варианты. Поменяйте только название |
||||
или описание или проходной балл. Сохраните. |
||||
|
||||
**Ожидается:** |
||||
- Сообщение «Сохранено.» (без форка). |
||||
- `version` не вырос; метаданные обновились на активной версии. |
||||
|
||||
> Логика: форк делается только если после попыток меняется **содержание** |
||||
> (вопросы/варианты). Чисто косметические правки шапки версию не плодят. |
||||
|
||||
### Сценарий 1.4. Каталог показывает только активную версию |
||||
|
||||
1. После 1.2 откройте `/tests` под автором и под не-автором (если есть назначения). |
||||
|
||||
**Ожидается:** |
||||
- В каталоге — одна карточка теста с пометкой `v.2` (активная). Версия 1 в каталог не попадает, но видна автору на странице «Версии» теста. |
||||
|
||||
### Сценарий 1.5. Ручное переключение активной версии |
||||
|
||||
1. Получите id v1 и v2: `SELECT id, version, is_active FROM test_versions WHERE test_id=...` |
||||
2. Сделайте активной v1: |
||||
```bash |
||||
curl -X POST -b cookies.txt \ |
||||
http://<host>:3108/api/tests/<test_id>/versions/<v1_id>/activate |
||||
``` |
||||
(cookie сессии берёте из браузера или логином через `/api/auth/login`). |
||||
|
||||
**Ожидается:** |
||||
- Ответ `{ ok: true, activeVersionId: "<v1_id>" }`. |
||||
- В БД: `is_active = true` только у v1, у v2 — `false`. |
||||
- В каталоге карточка теста снова показывает `v.1`. |
||||
|
||||
### Сценарий 1.6. Деактивация цепочки целиком |
||||
|
||||
1. В редакторе снимите чекбокс **«Цепочка активна»** и сохраните. |
||||
|
||||
**Ожидается:** |
||||
- В каталоге `/tests` теста больше не видно (ни в visible, ни у не-авторов). |
||||
- У автора он появляется в блоке **«Скрытые вами»** (внизу каталога). |
||||
- В БД: `tests.is_active = false`, версии и попытки нетронуты. |
||||
- Включение чекбокса обратно возвращает тест в каталог. |
||||
|
||||
### Сценарий 1.7. Корректность истории по старым попыткам |
||||
|
||||
> Полноценный разбор пользовательских ответов появится в **E1.4** вместе |
||||
> с UI прохождения. Сейчас минимально проверяем, что данные старой версии |
||||
> не повреждены. |
||||
|
||||
1. После 1.2 в БД: |
||||
```sql |
||||
SELECT q.text |
||||
FROM questions q |
||||
JOIN test_versions tv ON tv.id = q.test_version_id |
||||
WHERE tv.test_id = '<test_id>' AND tv.version = 1; |
||||
``` |
||||
2. **Ожидается:** видны вопросы **в том виде, в каком они были до правки** |
||||
(а не текущая версия v2). Эта же выборка должна совпадать с |
||||
`q.test_version_id` любой попытки, которую вы создали в 1.2. |
||||
|
||||
### Что фиксировать как баг |
||||
|
||||
- После правки **с попытками** в БД остался один `test_versions`-ряд (нет форка). |
||||
- После правки **без попыток** появилась `version = 2` (лишний форк). |
||||
- При активации одной версии другие не сбросились в `is_active = false`. |
||||
- Каталог показывает неактивную версию или скрытый тест. |
||||
- Сообщение в UI после сохранения не совпадает с реальным поведением (форк есть, текст «Сохранено.» без уточнения, или наоборот). |
||||
## Часть 1. Версии теста — что меняется при правках |
||||
|
||||
### О чём вообще задача |
||||
|
||||
Когда автор правит тест, в системе важно не сломать историю прохождений |
||||
сотрудников. Поэтому правила такие: |
||||
|
||||
- Пока **никто не прошёл** тест — автор правит на месте, версия одна. |
||||
- Как только **хотя бы один сотрудник прошёл** тест — следующее сохранение |
||||
изменений создаёт **новую версию** (v2, v3, …), старая сохраняется. |
||||
- В каталоге всегда видна **только одна** активная версия. |
||||
- Автор может **скрыть** тест целиком (чекбокс «Цепочка активна»). |
||||
- Автор может **переключить** активную версию на другую из истории. |
||||
|
||||
> Сейчас на сайте нельзя пройти тест сотруднику и нельзя из UI открыть |
||||
> историю версий — это будет в следующих спринтах. Поэтому из шести |
||||
> правил тестировщик пока проверяет четыре, остальные помечены ниже. |
||||
|
||||
--- |
||||
|
||||
### 1.1. Создание нового теста |
||||
|
||||
**Что проверяем:** автор может создать тест с нуля. |
||||
|
||||
**Как проверять:** |
||||
1. Откройте [https://edullm.pirogov.ai/](https://edullm.pirogov.ai/) и войдите. |
||||
2. Нажмите в шапке иконку **«Тесты»** (список) → попадаете в каталог. |
||||
3. Нажмите кнопку **«Создать тест»**. |
||||
4. В появившемся окне заполните **Название** (например, «Тест A»), |
||||
при желании — Описание. |
||||
5. Нажмите **«Создать»**. |
||||
|
||||
**Что должно произойти:** |
||||
- Открывается экран редактора нового теста. |
||||
- В поле «Название» — то, что вы ввели. |
||||
- Список вопросов пуст, счётчик «Вопросы (0)». |
||||
- Внизу — кнопка **«Сохранить»** и чекбокс **«Цепочка активна»** (по |
||||
умолчанию включён). |
||||
|
||||
**Если что-то не так — баг:** |
||||
- Окно «Создать тест» не открывается. |
||||
- После «Создать» никуда не перенаправило. |
||||
- В поле «Название» в редакторе пусто, хотя ввели текст. |
||||
- Список тестов в каталоге не обновился (не появилась новая карточка). |
||||
|
||||
--- |
||||
|
||||
## Часть 2. AI-функции (E1.2 + E1.8) |
||||
### 1.2. Правка теста до прохождений (версия не растёт) |
||||
|
||||
**Что проверяем:** пока никто не проходил тест, автор может править его |
||||
сколько угодно — это всё одна и та же версия. |
||||
|
||||
### Заметка о ключе |
||||
**Как проверять:** |
||||
1. Откройте только что созданный «Тест A» (если уже не открыт): шапка → **«Тесты»** → нажмите на карточку теста. |
||||
2. Нажмите **«Добавить вопрос»** — появится карточка вопроса. |
||||
3. Введите текст вопроса. |
||||
4. Заполните 3–4 варианта ответа в поле «Вариант ответа», у одного из них поставьте чекбокс «Правильный» (квадратик слева от текста). |
||||
5. Добавьте ещё один-два вопроса тем же способом. |
||||
6. Нажмите **«Сохранить»** в нижней панели. |
||||
|
||||
Изначально в ТЗ предполагалось хранить ключ в БД и вводить на `/settings`. |
||||
По согласованию ключ **общий** и хранится в `ENV` контейнера |
||||
(`DEEPSEEK_API_KEY` / `OPENAI_API_KEY`). Страница `/settings` остаётся, |
||||
но в ней — только статус и кнопка проверки подключения. Поле ввода ключа в UI **не нужно** (это не баг). |
||||
**Что должно произойти:** |
||||
- Под шапкой появляется надпись **«Сохранено.»** (без слов про новую версию). |
||||
- Если перезагрузить страницу — все вопросы и варианты на месте. |
||||
|
||||
### A.0. Негативный кейс — ключ не задан |
||||
**Повторите правку:** |
||||
1. На том же экране **измените** текст одного вопроса, **добавьте** ещё один вариант к другому, **удалите** третий вопрос (кнопка «корзина» справа в карточке вопроса). |
||||
2. Нажмите **«Сохранить»**. |
||||
|
||||
1. На сервере уберите `DEEPSEEK_API_KEY` из окружения и перезапустите контейнер. |
||||
2. Откройте `/settings`. |
||||
**Что должно произойти:** |
||||
- Снова надпись **«Сохранено.»**. |
||||
- Никаких слов «создана новая версия». |
||||
- Перезагрузка страницы — изменения сохранились. |
||||
|
||||
**Ожидается:** |
||||
- Бейдж «Не задан» (красный). |
||||
- Блок «Как задать ключ» с примером `.env`. |
||||
- Кнопка **«Проверить подключение»** возвращает красный блок с текстом про незаданный ключ. |
||||
- В редакторе при нажатии **«Сгенерировать по сетке» / «по названию» / «Проверить тест» / «Улучшить тест» / «AI: вопрос»** появляется confirm: |
||||
«… Открыть Настройки?» → согласие открывает `/settings`. |
||||
**Если что-то не так — баг:** |
||||
- Появляется сообщение про «новую версию» (его быть не должно — попыток ещё нет). |
||||
- Изменения не сохранились после перезагрузки страницы. |
||||
- Сообщение «Сохранено.» не появилось вовсе. |
||||
|
||||
После проверки верните ключ и `docker compose ... up -d` — переходим к позитивным сценариям. |
||||
--- |
||||
|
||||
### 1.3. Правка после прохождений (создаётся v2) |
||||
|
||||
### A.1. `/settings` → «Проверить подключение» |
||||
> ⏳ **Сейчас недоступно для проверки.** |
||||
> |
||||
> На сайте пока нет страницы для прохождения теста сотрудником, поэтому |
||||
> тестировщик не может «накопить» попытки и проверить эту логику через UI. |
||||
> Сценарий вернётся в инструкцию вместе со следующим спринтом, когда |
||||
> появится страница прохождения. |
||||
|
||||
--- |
||||
|
||||
### 1.4. Каталог показывает только активные тесты |
||||
|
||||
**Что проверяем:** в каталоге нет неактивных/скрытых тестов. |
||||
|
||||
**Как проверять:** |
||||
1. На экране редактора любого теста снимите внизу чекбокс |
||||
**«Цепочка активна»** и нажмите **«Сохранить»**. |
||||
2. Перейдите в шапке на **«Тесты»** (каталог). |
||||
|
||||
**Что должно произойти:** |
||||
- Карточки этого теста в основном списке нет. |
||||
- Внизу страницы каталога есть раскрывающийся блок **«Скрытые вами цепочки (N)»**. Раскройте его — там видно ваш тест. |
||||
- Нажмите **«Открыть»** рядом с тестом — снова попадаете в редактор. |
||||
- Поставьте обратно галку **«Цепочка активна»** → **«Сохранить»**. |
||||
- Снова перейдите в **«Тесты»** — тест опять в основном списке каталога. |
||||
|
||||
**Если что-то не так — баг:** |
||||
- После снятия галки тест остаётся в обычном каталоге. |
||||
- Тест полностью пропал и его не видно нигде, даже в «Скрытых». |
||||
- После возврата галки тест не вернулся в основной каталог. |
||||
|
||||
--- |
||||
|
||||
### 1.5. Ручное переключение активной версии |
||||
|
||||
> ⏳ **Сейчас недоступно для проверки.** |
||||
> |
||||
> Страница с историей версий теста (где можно нажать «сделать активной») |
||||
> ещё не сделана. Появится в следующем спринте. |
||||
|
||||
--- |
||||
|
||||
### 1.6. История прохождений после правок |
||||
|
||||
> ⏳ **Сейчас недоступно для проверки** — см. 1.3 и 1.5. |
||||
|
||||
--- |
||||
|
||||
1. На `/settings` нажмите **«Проверить подключение»**. |
||||
## Часть 2. AI-функции в редакторе теста |
||||
|
||||
**Ожидается:** |
||||
- В течение нескольких секунд — зелёный блок: `OK · <provider> / <model> · <ms> мс` и сэмпл ответа. |
||||
- Provider/Model совпадают с ENV (`deepseek` + `deepseek-chat` по умолчанию). |
||||
### Как проверять, что AI вообще работает |
||||
|
||||
### A.2. «Сгенерировать тест по названию» (E1.8) |
||||
**Что проверяем:** ключ к AI задан и сервис отвечает. |
||||
|
||||
1. Создайте новый пустой тест (никаких вопросов). |
||||
2. В редакторе нажмите **«Сгенерировать по названию»**. |
||||
3. На запрос «Сколько вопросов?» введите, например, `8`; «Сколько вариантов?» — `4`. |
||||
4. Дождитесь готовности → confirm «Применить как черновик?». |
||||
**Как проверять:** |
||||
1. В шапке нажмите иконку **«Настройки»** (шестерёнка). |
||||
2. Посмотрите блок «Подключение к LLM»: |
||||
- **Статус ключа** — должно быть зелёное **«Задан»**. |
||||
- **Провайдер** и **Модель** — заполнены. |
||||
3. Нажмите кнопку **«Проверить подключение»**. |
||||
|
||||
**Ожидается:** |
||||
- Кнопка **активна только** когда поле «Название» заполнено. Если очистить название — нажатие даёт алерт «Сначала заполните название теста.» и фокус возвращается в название. |
||||
- Появляется ровно ~8 вопросов по ~4 варианта (модель может слегка отклониться по инструкции, это допустимо). |
||||
**Что должно произойти:** |
||||
- В течение 1–10 секунд под кнопкой появляется **зелёный** блок |
||||
с текстом вида **«OK · deepseek / deepseek-chat · 1234 мс»**. |
||||
|
||||
**Если что-то не так:** |
||||
- Если статус **«Не задан»** (красный) — сообщите разработчику, не задан ключ. Тестировать AI-функции в этом режиме не нужно, кроме одного сценария ниже (2.7). |
||||
- Если кнопка отдала **красный** блок «Ошибка» при заданном ключе — это баг, прикладывайте текст ошибки к тикету. |
||||
|
||||
--- |
||||
|
||||
### 2.1. Сгенерировать тест по названию |
||||
|
||||
**Простыми словами:** автор пишет только тему, AI сам придумывает вопросы. |
||||
|
||||
**Как проверять:** |
||||
1. **«Тесты»** → **«Создать тест»** → название, например, **«Гигиена рук»**, описание можно оставить пустым → **«Создать»**. |
||||
2. В редакторе нажмите кнопку **«По названию»** (фиолетовая, в блоке «AI-помощник» → «Создать вопросы»). |
||||
3. На вопрос «Сколько вопросов сгенерировать?» введите, например, `8` → **OK**. |
||||
4. На вопрос «Сколько вариантов в каждом вопросе?» введите, например, `4` → **OK**. |
||||
5. Подождите 5–20 секунд. |
||||
6. Появится подтверждение «Готово: «…», вопросов — N. Применить как черновик? Текущие вопросы будут заменены». Нажмите **OK**. |
||||
|
||||
**Что должно произойти:** |
||||
- В списке появилось примерно 8 вопросов на тему гигиены рук, в каждом примерно 4 варианта ответа на русском языке. |
||||
- В каждом вопросе хотя бы один вариант помечен как «Правильный» (галка слева от текста варианта). |
||||
- Внизу можно нажать **«Сохранить»** — тест сохраняется. |
||||
|
||||
**Дополнительно (что блокировка названия работает):** |
||||
1. Создайте ещё один тест, в редакторе **очистите поле «Название»**. |
||||
2. Нажмите **«По названию»**. |
||||
3. Должен появиться алерт **«Сначала заполните название теста.»**, курсор перейдёт в поле «Название». Никакой генерации не происходит. |
||||
|
||||
**Если что-то не так — баг:** |
||||
- Кнопка **«По названию»** работает при пустом названии (без алерта). |
||||
- Сгенерированные вопросы — не на русском или не по теме названия. |
||||
- В вопросе нет ни одного правильного варианта. |
||||
- Подтверждение «Применить?» не появилось — вопросы заменились молча. |
||||
- Отказ в подтверждении (Cancel) всё равно заменил вопросы. |
||||
|
||||
--- |
||||
|
||||
### 2.2. Сгенерировать тест по сетке |
||||
|
||||
**Простыми словами:** автор сам задаёт «скелет» — сколько вопросов и |
||||
сколько вариантов; AI заполняет вопросы по этому скелету. |
||||
|
||||
**Как проверять:** |
||||
1. Создайте новый тест с названием **«Тест по сетке»**. |
||||
2. Нажмите **«Добавить вопрос»** пять раз — получится 5 пустых карточек. |
||||
3. В **третьей и пятой** карточках поставьте галку **«Несколько правильных ответов»**. |
||||
4. В каждом вопросе по умолчанию 0 вариантов — нажмите **«Добавить вариант»** в каждом вопросе по 3 раза, чтобы стало по 3 варианта. |
||||
5. Нажмите кнопку **«По текущей сетке»** в блоке «AI-помощник». |
||||
|
||||
**Что должно произойти:** |
||||
- В списке снова 5 вопросов (не больше, не меньше). |
||||
- В каждом — по 3 варианта. |
||||
- В третьем и пятом вопросах несколько вариантов помечены правильными; |
||||
в остальных — ровно один. |
||||
- Тексты — на русском, по теме названия. |
||||
- В каждом вопросе хотя бы один вариант помечен как правильный. |
||||
- Отказ в confirm не меняет редактор; согласие — заменяет. |
||||
- Сохранение работает, в БД появляется версия с этими вопросами. |
||||
|
||||
### A.3. «Сгенерировать тест по сетке» (E1.2 — было) |
||||
**Если что-то не так — баг:** |
||||
- Стало другое число вопросов или вариантов (не 5×3). |
||||
- В третьем/пятом вопросе только один правильный ответ, а в остальных — несколько. |
||||
- Пришла ошибка типа **«AI: ошибка»** без понятного объяснения. |
||||
|
||||
1. Откройте тест, в котором уже руками настроены 5 вопросов, по 3 варианта в каждом, 2 из вопросов помечены как «Несколько правильных». |
||||
2. Нажмите **«Сгенерировать по сетке»**. |
||||
--- |
||||
|
||||
### 2.3. Проверить тест |
||||
|
||||
**Простыми словами:** AI читает весь тест и пишет, что в нём не так. |
||||
|
||||
**Как проверять:** |
||||
1. Откройте любой тест с 3+ вопросами (например, «Гигиена рук» из 2.1). |
||||
2. Желательно специально испортить пару вопросов: переписать |
||||
формулировку расплывчато («что-то про что-то»), сделать варианты |
||||
ответа очень похожими друг на друга или явно дурацкими. |
||||
3. Нажмите **«Сохранить»**. |
||||
4. Нажмите кнопку **«Проверить»** в блоке «AI-помощник» → «Улучшить существующее». |
||||
|
||||
**Что должно произойти:** |
||||
- Открывается окно «Проверка теста». |
||||
- Сверху — цветная плашка с одним из вердиктов: **«Годен»** (зелёный), |
||||
**«Есть замечания»** (жёлтый) или **«Серьёзные проблемы»** (красный) |
||||
+ одно-два предложения резюме. |
||||
- Ниже — список разделов: «Чёткость формулировок», «Качество дистракторов», |
||||
«Охват темы», «Сбалансированность сложности». Под каждым — конкретные |
||||
пункты, что улучшить. |
||||
- Закрытие крестиком сверху или кнопкой «Закрыть» внизу — работает. |
||||
- В тесте при этом **ничего не меняется**, AI только советует. |
||||
|
||||
**Если что-то не так — баг:** |
||||
- Окно пустое или текст не на русском. |
||||
- Все вопросы AI признал хорошими, хотя вы их специально испортили. |
||||
- После закрытия окна в тесте появились/исчезли вопросы. |
||||
|
||||
**Ожидается:** |
||||
- Возвращается ровно 5 вопросов. |
||||
- В тех же позициях, что у вас стояли «Несколько правильных», — у новых вопросов несколько правильных вариантов. |
||||
- Число вариантов в каждом вопросе совпадает. |
||||
- При несовпадении сетки эндпоинт вернул бы 502 с кодом `llm_shape` (модель «не попала») — допустимая редкая ошибка, повторите. |
||||
--- |
||||
|
||||
### A.4. «Проверить тест» (E1.8) |
||||
### 2.4. Улучшить весь тест |
||||
|
||||
**Простыми словами:** AI предлагает улучшенные формулировки и варианты; |
||||
автор отмечает галками, что применить. |
||||
|
||||
**Как проверять:** |
||||
1. Откройте тест из 2.3 (с теми же намеренно слабыми вопросами). |
||||
2. Нажмите **«Сохранить»** на всякий случай. |
||||
3. Нажмите кнопку **«Улучшить»**. |
||||
|
||||
**Что должно произойти:** |
||||
- Открывается окно «Улучшение теста». |
||||
- Сверху подпись «Отметьте вопросы… N из M» (M — всего вопросов, N — где AI предложил изменения). |
||||
- Каждый изменённый вопрос — отдельный блок: |
||||
- Чекбокс **«Вопрос #N»** (по умолчанию **отмечен**). |
||||
- Слева — «Было» (старый текст и варианты, изменённые куски зачёркнуты). |
||||
- Справа — «Стало» (новые формулировки, выделены). |
||||
- Правильные варианты помечены галочкой **✓**. |
||||
- Внизу — две кнопки: **«Отмена»** и **«Применить выбранное»**. |
||||
|
||||
**Проверьте применение по выбору:** |
||||
1. Снимите галки у двух вопросов из списка. |
||||
2. Нажмите **«Применить выбранное»**. |
||||
|
||||
**Что должно произойти:** |
||||
- Окно закрывается. |
||||
- В редакторе **только** отмеченные вопросы заменены на улучшенные; |
||||
два вопроса, у которых вы сняли галки, остались в прежнем виде. |
||||
- Появляется подсказка «Изменения применены. Не забудьте сохранить.» |
||||
- После **«Сохранить»** — обычное «Сохранено.» |
||||
|
||||
**Если что-то не так — баг:** |
||||
- Поменялось **число** вопросов или вариантов в каких-то вопросах |
||||
(должно остаться как было). |
||||
- В вопросе изменилось значение «Несколько правильных ответов» (галка |
||||
переключилась сама). |
||||
- Изменились вопросы, у которых вы сняли галку. |
||||
- Кнопка «Отмена» всё равно применила изменения. |
||||
- В колонках «Было» и «Стало» одинаковый текст (нет смысла предлагать). |
||||
|
||||
1. Создайте тест с парой нарочно слабых мест: |
||||
- один вопрос с длинной мутной формулировкой; |
||||
- один вопрос, где все варианты слишком похожи или в качестве «дистракторов» — очевидная ерунда. |
||||
2. Нажмите **«Проверить тест»**. |
||||
--- |
||||
|
||||
**Ожидается:** |
||||
- Открывается модалка «Проверка теста». |
||||
- Есть цветная плашка с одним из вердиктов: **Годен / Есть замечания / Серьёзные проблемы**, и краткое резюме (1–2 предложения). |
||||
- Ниже — список разделов («Чёткость формулировок», «Качество дистракторов», «Охват темы», «Сбалансированность сложности»). Разделы без замечаний пропускаются. |
||||
- В списке — конкретные пункты на русском, по делу. |
||||
- Закрытие модалки крестиком или кнопкой «Закрыть» работает. |
||||
### 2.5. AI: вопрос/переформулировать |
||||
|
||||
### A.5. «Улучшить тест» (E1.8) — массовое было → стало |
||||
**Простыми словами:** работа с одним вопросом. Если поле пустое — AI его |
||||
придумает; если уже заполнено — переформулирует красивее, варианты не трогает. |
||||
|
||||
1. Возьмите тест из A.4 (с ≥ 3 вопросами). |
||||
2. Нажмите **«Улучшить тест»**. |
||||
**Как проверять (новый вопрос):** |
||||
1. В любом тесте нажмите **«Добавить вопрос»** — появилась пустая карточка. |
||||
2. **Не трогайте** поле «Формулировка вопроса». |
||||
3. Нажмите **«Добавить вариант»** 4 раза — должно стать 4 пустых варианта. |
||||
4. Нажмите кнопку **«AI: вопрос/переформулировать»** в этой карточке. |
||||
|
||||
**Ожидается:** |
||||
- Открывается модалка с заголовком «Улучшение теста» и подсказкой «Отмечено N из M». |
||||
- Каждый изменённый вопрос — отдельная карточка: |
||||
- чекбокс «Вопрос #N» (по умолчанию **отмечен**); |
||||
- две колонки **Было** / **Стало**; |
||||
- изменённый текст в «Было» зачёркнут, в «Стало» — выделен; |
||||
- правильные варианты помечены ✓. |
||||
- Снимите галку с одного-двух вопросов и нажмите **«Применить выбранное»**. |
||||
- В редакторе **только** отмеченные вопросы заменены на улучшенные; остальные остались как были. |
||||
- Появляется надпись «Изменения применены. Не забудьте сохранить.» — нажмите **«Сохранить»** и проверьте версионирование (см. Часть 1). |
||||
- **Сетка не меняется**: число вопросов, число вариантов в каждом и значение «Несколько правильных» совпадают с исходными. Если модель «слетела» — эндпоинт возвращает 502 с `llm_shape` и UI показывает алерт; это не баг логики. |
||||
**Что должно произойти:** |
||||
- Поле «Формулировка вопроса» заполнено осмысленным текстом по теме теста. |
||||
- Все 4 варианта заполнены. |
||||
- Ровно один помечен как правильный. |
||||
- Внизу появляется строка статуса **«AI: вопрос сгенерирован.»** |
||||
|
||||
### A.6. AI-кнопка на конкретном вопросе (E1.2) |
||||
**Как проверять (переформулировать существующий):** |
||||
1. Возьмите готовый вопрос с уже заполненной формулировкой. |
||||
2. Нажмите **«AI: вопрос/переформулировать»** в его карточке. |
||||
|
||||
Сценарий «новый вопрос»: |
||||
**Что должно произойти:** |
||||
- Меняется **только текст вопроса** — варианты ответа остаются прежними, |
||||
правильные варианты те же. |
||||
- Статус **«AI: формулировка обновлена.»** |
||||
|
||||
1. Добавьте вопрос, **поле текста оставьте пустым**, число вариантов = 4, «Несколько правильных» — выкл. |
||||
2. Нажмите **«AI: вопрос/переформулировать»** на этом вопросе. |
||||
**Если что-то не так — баг:** |
||||
- На пустом вопросе AI ничего не сгенерировал. |
||||
- На заполненном вопросе AI поменял варианты ответа или правильность — |
||||
должен трогать только формулировку. |
||||
- Получилось 0 или 1 правильных вариантов в новом вопросе (надо ровно 1 |
||||
для одиночного выбора). |
||||
|
||||
**Ожидается:** заполнен текст вопроса и все 4 варианта; ровно один помечен правильным; внизу — статус «AI: вопрос сгенерирован.» |
||||
--- |
||||
|
||||
Сценарий «переформулировать»: |
||||
### 2.6. Импорт документа |
||||
|
||||
1. Возьмите готовый вопрос с заполненным текстом. |
||||
2. Нажмите ту же кнопку. |
||||
**Простыми словами:** автор загружает PDF/Word/текст со статьёй — |
||||
AI читает файл и сам предлагает черновик теста. |
||||
|
||||
**Ожидается:** меняется **только текст** вопроса (вариант ответа и правильность не трогаются), статус «AI: формулировка обновлена.» |
||||
**Подготовьте файл:** возьмите PDF или DOCX на 1–3 страницы со связным |
||||
русским текстом (например, любую методичку или статью). Лимит — 16 МБ. |
||||
|
||||
### A.7. Импорт документа (E1.3) |
||||
**Как проверять:** |
||||
1. В редакторе любого нового теста (можно пустого) → блок «AI-помощник» |
||||
→ **«Импортировать»** → нажмите большую кнопку **«Загрузить документ (PDF, DOCX, TXT, MD)»** → выберите файл. |
||||
2. Подождите 5–30 секунд. |
||||
|
||||
1. Подготовьте файл `sample.pdf` или `sample.docx` со связным текстом (1–3 страницы) на русском. |
||||
2. В редакторе → AI-панель → **«Импорт документа»** → выберите файл. |
||||
**Что должно произойти:** |
||||
- Появляется подтверждение «Сгенерировано: «…», вопросов: N. Применить как новый черновик? Текущие вопросы будут заменены». Нажмите **OK**. |
||||
- Тест заполнен вопросами по содержанию загруженного документа. |
||||
- Можно сохранить кнопкой **«Сохранить»**. |
||||
|
||||
**Ожидается:** |
||||
- Прогресс «Загружаем «sample.pdf»…». |
||||
- Confirm «Сгенерировано: «<title>», вопросов: N. Применить как новый черновик?» → согласие заменяет вопросы, отказ ничего не меняет. |
||||
- При файле > 16 МБ — ошибка от Flask (413/500), это норма (лимит). |
||||
- При файле неподдерживаемого формата (`.xlsx`, `.png`) — алерт «Неподдерживаемый формат…». |
||||
- При **отсутствующем** ключе AI: вместо confirm — алерт с текстом «Автогенерация выключена…» и первыми 600 символами извлечённого текста; вопросы **не** заменяются. |
||||
**Дополнительно — отказ:** |
||||
1. Повторите загрузку, но в подтверждении нажмите **«Отмена»**. |
||||
2. Тест должен остаться **в прежнем виде**, ничего не подменилось. |
||||
|
||||
### A.8. Единая ошибка при отсутствии ключа |
||||
**Дополнительно — большой файл:** |
||||
1. Возьмите файл больше 16 МБ. |
||||
2. Загрузите его. |
||||
|
||||
1. Уберите ключ (как в A.0). Откройте редактор любого теста. |
||||
2. По очереди нажимайте **«Сгенерировать по сетке»**, **«по названию»**, **«Проверить тест»**, **«Улучшить тест»**, **«AI: вопрос»**. |
||||
**Что должно произойти:** ошибка о слишком большом файле; вопросы не |
||||
подменились. |
||||
|
||||
**Ожидается:** в каждом случае confirm с предложением открыть **/settings**, не молчаливый алерт. На бэке — JSON `{ error, code, settingsUrl: "/settings" }`, статус 502. |
||||
**Дополнительно — неподдерживаемый тип:** |
||||
1. Возьмите файл `.xlsx` или картинку `.png`. |
||||
2. Попробуйте загрузить. |
||||
|
||||
### Что фиксировать как баг (AI) |
||||
**Что должно произойти:** алерт «Неподдерживаемый формат…»; вопросы не |
||||
подменились. |
||||
|
||||
- Кнопка **«Сгенерировать по названию»** позволяет жать без названия и не показывает алерт. |
||||
- Модалка **«Проверить тест»** пуста или содержит англ. текст. |
||||
- В **«Улучшить тест»** меняется число вопросов / число вариантов / «Несколько правильных», т.е. сетка слетела, и UI всё равно применил. |
||||
- В **«AI: вопрос»** на пустом вопросе варианты не сгенерированы; на заполненном — варианты заменены без ведома пользователя. |
||||
- Любая AI-ошибка показывается без ссылки на `/settings`, когда ключ действительно отсутствует. |
||||
- Импорт документа подменяет вопросы **без confirm**. |
||||
**Если что-то не так — баг:** |
||||
- Подтверждение не появилось — вопросы заменились молча. |
||||
- Отказ в подтверждении всё равно подменил вопросы. |
||||
- Большой файл не вызвал ошибку, а как-то «прошёл». |
||||
- Файл не на русском дал тест с непонятной кашей вместо вопросов. |
||||
|
||||
--- |
||||
|
||||
## Шпаргалка: что и где смотреть |
||||
|
||||
| Что | URL / SQL | |
||||
|---|---| |
||||
| Каталог | `/tests` | |
||||
| Редактор | `/tests/<id>/edit` | |
||||
| Версии теста | `GET /api/tests/<id>/versions` | |
||||
| Активность LLM | `/settings` + `POST /api/llm/ping` | |
||||
| `test_versions` | `SELECT id, version, is_active, parent_id, created_at FROM test_versions WHERE test_id = '<id>' ORDER BY version;` | |
||||
| Попытки | `SELECT id, test_version_id, status, created_at FROM test_attempts WHERE test_version_id IN (SELECT id FROM test_versions WHERE test_id='<id>');` | |
||||
|
||||
При баге прикладывайте: |
||||
- скрин редактора / модалки; |
||||
- ответ соответствующего эндпоинта (DevTools → Network → JSON); |
||||
- результат SQL из таблицы выше; |
||||
- `docker compose -f docker-compose.dev.yml logs --tail=200 testing-flask`. |
||||
### 2.7. Поведение, если ключа AI нет |
||||
|
||||
> Этот сценарий обычно проверять не нужно — он сработает автоматически, если разработчик уберёт ключ. |
||||
> Но если в каталоге AI вообще не работает, то проверьте именно это, чтобы понять — это баг или просто ключ не настроен. |
||||
|
||||
**Как проверять:** |
||||
1. **«Настройки»** → если статус **«Не задан»** (красный) — это и есть тестируемая ситуация. |
||||
2. Откройте любой тест и нажмите по очереди: |
||||
- **«По названию»** |
||||
- **«По текущей сетке»** |
||||
- **«Проверить»** |
||||
- **«Улучшить»** |
||||
- **«AI: вопрос/переформулировать»** в любой карточке |
||||
- **«Загрузить документ»** |
||||
|
||||
**Что должно произойти:** в каждом случае появляется понятное сообщение, |
||||
что AI не настроен, **и предложение открыть «Настройки»**. После согласия |
||||
— открывается страница `/settings`. Никакого «AI: ошибка» без объяснений. |
||||
|
||||
**Если что-то не так — баг:** |
||||
- Сообщение об ошибке без слов «Настройки». |
||||
- Ссылка/кнопка «Открыть Настройки» не ведёт на нужную страницу. |
||||
- Сайт молча ничего не делает после нажатия AI-кнопки. |
||||
|
||||
--- |
||||
|
||||
## Памятка: общий алгоритм отчёта о баге |
||||
|
||||
Если что-то идёт не так, к тикету приложите: |
||||
|
||||
1. **URL страницы**, на которой воспроизвели баг (полностью, из адресной |
||||
строки). |
||||
2. **Шаги** — что именно нажимали по порядку (1-2-3). |
||||
3. **Что увидели** против **что ожидали увидеть** (по описанию выше). |
||||
4. **Скриншот** экрана с проблемой (для модалок — со всем содержимым окна). |
||||
5. Если ошибка — **точный текст** сообщения. |
||||
6. **Учётная запись**, под которой воспроизвели (логин, без пароля). |
||||
|
||||
Этого достаточно — лезть в консоль/код/базу не нужно и не надо. |
||||
|
||||
Loading…
Reference in new issue