Смоук-чеклист¶
Большую часть поведения проверяют автоматические тесты. Здесь собраны процедуры для наборов в настоящем QGIS и короткий список проверок, которым ещё нужен человек.
Автоматические наборы¶
python3 -m unittest discover -s tests -t .— быстрый набор. Идёт без QGIS.tests/real_qgis_smoke.pyставит собранный ZIP в настоящий QGIS.tests/real_qgis_workflows.pyгоняет живые сценарии со слоями, Processing и жизненным циклом Qt, проверки экранов иtests/real_qgis_e2e.py.tests/real_qgis_e2e.pyведёт весь плагин так, как это делает человек: печатает запрос, отправляет, применяет, останавливает и откатывает. Модель —tests/e2e_model.py, заскриптованный OpenAI-совместимый сервер на127.0.0.1, который запоминает каждый запрос.
Чтобы добавить сквозной сценарий, унаследуйте ScenarioCase, поставьте ходы
модели через say(), call(), calls() и fail(), затем ведите панель
через ask(), apply() и wait_idle(). Сценарий падает на неожиданном
запросе или неиспользованном ходе. Наборы запускаются Python из QGIS:
QT_QPA_PLATFORM=offscreen python3 tests/real_qgis_workflows.py
Эталоны экранов¶
tests/real_qgis_visual.py собирает каждый экран без модели и проверяет его
тремя способами: структуру виджетов по JSON-эталонам в
tests/data/ui/structure (только английский), обрезанный текст и выход за
границы на английском и русском (UI_LOCALE=ru) и пиксели по PNG-эталонам в
tests/data/ui/pixels. Пиксели сравниваются только в задаче CI ui-pixels,
на одном образе QGIS, закреплённом по digest. Каждый запуск CI прикладывает
галерею экранов index.html.
После намеренного изменения интерфейса перезапишите эталоны структуры и просмотрите diff JSON:
UI_UPDATE_GOLDENS=1 QT_QPA_PLATFORM=offscreen python3 tests/real_qgis_workflows.py real_qgis_visual
Пиксельные эталоны берутся только из закреплённого образа, никогда из
настольного QGIS. Либо скопируйте картинки ui-actual из артефакта
ui-pixels упавшего запуска в tests/data/ui/pixels, либо запустите тот же
образ локально:
docker run --rm --platform linux/amd64 -v "$PWD":/repo -w /repo \
-e QT_QPA_PLATFORM=offscreen -e UI_PIXEL_BASELINE=1 -e UI_UPDATE_GOLDENS=1 \
qgis/qgis@sha256:23c12670e69909e8659a5c098aa307996735a5763b9ff9c3268bdeeee1a10916 \
sh -c 'python3 tests/real_qgis_workflows.py real_qgis_visual && UI_LOCALE=ru python3 tests/real_qgis_workflows.py real_qgis_visual'
Сценарии с настоящей моделью¶
tests/real_qgis_live.py даёт настоящей модели обычные задачи: раскраску по
классам, вопрос на подсчёт, подписи, буфер в метрах. Проверяется только
результат, потому что путь модель выбирает сама. Падение значит, что промпт,
навык или схема инструмента сбивает настоящие модели, или провайдер что-то
поменял.
В CI его гоняет workflow live-model в QGIS. Он никогда не запускается на
push и pull request: запускайте его из вкладки Actions или поставьте галочку
live_model_check при выпуске. Нужны переменные LIVE_MODEL_URL и
LIVE_MODEL и секрет LIVE_MODEL_KEY. Траты ограничены на запуск, на набор и
таймаутом задачи; поставьте лимит трат и у провайдера.
Локально подойдёт любой OpenAI-совместимый сервер, с локальной моделью — бесплатно:
LIVE_MODEL_URL=http://localhost:11434/v1 LIVE_MODEL=qwen3 LIVE_MODEL_KEY=local \
QT_QPA_PLATFORM=offscreen python3 tests/real_qgis_workflows.py real_qgis_live
Потолки токенов¶
Две проверки сверяют расход с tests/data/token_ceilings.json:
- Скриптовая, на каждый push.
tests/real_qgis_e2e.pyизмеряет самый большой системный промпт, самый большой список схем инструментов и самый маленький запрос (base_chars) в символах и сравнивает с разделомscripted. Числа сохраняются вrequest_sizes.jsonв артефактеe2e-screens-*. - С настоящей моделью, вручную и перед выпуском.
tests/real_qgis_live.pyзаписывает токены промпта, ответа, их сумму и число запросов каждого сценария вlive_usage.json(артефактlive-token-usage) и сравнивает с разделомlive. Потолки относятся к модели, на которой их измерили; с другой моделью запуск только сообщает числа. Workflow задаётLIVE_REQUIRE_CEILINGS=1, поэтому там сценарий без потолка падает.
Обновляйте потолки, только когда расход изменился намеренно, и пишите причину
в коммите. Потолки для настоящей модели стройте по двум-трём запускам
workflow live-model: скрипт берёт наибольшее значение каждой метрики и
добавляет запас (30 % для настоящей модели, 10 % для скриптовой).
gh run download <run-id> -n live-token-usage -D /tmp/live-1
python3 tests/token_ceilings.py /tmp/live-1/live_usage.json /tmp/live-2/live_usage.json
Скриптовые потолки берутся из одного прогона скриптовых сценариев:
E2E_ARTIFACTS=/tmp/e2e QT_QPA_PLATFORM=offscreen python3 tests/real_qgis_workflows.py real_qgis_e2e
python3 tests/token_ceilings.py /tmp/e2e/request_sizes.json
Перед коммитом просмотрите diff: резко выросший потолок — это и есть регрессия, ради которой проверка существует.
Ручные проверки¶
Им нужен настоящий провайдер, настоящий сетевой сервис или взгляд человека.
- Провайдеры. Проверка подключения и один запуск с вызовами инструментов
на OpenAI, Anthropic (формат
autoшлёт на/messages), OpenRouter, Google Gemini и Ollama по адресуhttp://localhost:11434/v1с пустым ключом. Удалённый адрес без ключа сообщает, что нет ключа. - Рассуждение. Локальная рассуждающая модель (дистиллят DeepSeek-R1,
QwQ) держит рассуждение в свёрнутой строке Размышление, а не в ответе.
Anthropic с бюджетом размышлений 4096 доводит запуск с инструментами до
конца. DeepSeek с включённым рассуждением отвечает на два вопроса с
инструментами в одном разговоре без ошибки 400 о
reasoning_content. - Русский QGIS. Переключите интерфейс QGIS на русский и перезапустите. Панель, настройки и карточка плана на русском, с верными формами числа (1 шаг, 2 шага, 5 шагов). Немецкий откатывается на английский. Агент отвечает на том языке, на котором вы пишете.
- Темы. В светлом и тёмном QGIS, а также со Светлой темой панели в
тёмном QGIS читаются панель, настройки, списки
@и/, меню и карточки. Значки чёткие на экране с высокой плотностью. - Движение. Компас качается, пока агент работает, и успокаивается, когда он закончил. Списки действий и Размышление сворачиваются плавно, даже при многих щелчках подряд.
- OpenStreetMap. Скачай кафе в Твери добавляет точечный слой. Охват шире пяти градусов отклоняется до отправки.
- Открытые данные. Поиск Sentinel-2 просит согласия с названием Planetary Computer и перечисляет снимки; загрузка одного добавляет растр. Добавь регионы Кении добавляет 47 регионов. Коннектор, выключенный в настройках, отклоняется.
- Веб-инструменты. Поиск, чтение страницы и геокодирование каждый раз
спрашивают. Адрес
https://nominatim.openstreetmap.orgкак свой геокодер не сохраняется. - Другие плагины. С установленным qgis2web запуск его экспорта спрашивает подтверждение для опасного действия и открывает его окно. Установка плагина из репозитория спрашивает дважды, после чего плагин виден в Управлении модулями, а его алгоритмы — в панели Processing.
- Долгий шаг. Буфер на слое в десятки тысяч объектов: карта двигается, пока он идёт, шаг показывает прогресс, ■ отменяет его и шаги после него.
- Перезапуск. После перезапуска QGIS разговор возвращается со списками действий и карточками плана, а уточняющий вопрос опирается на прежний контекст. Заметки проекта остаются при своём проекте.
- Выгрузка. Перезагрузка плагина во время запроса не роняет QGIS.
- Журнал прогона. Включите Журнал прогона в Настройки → Приватность и
примените план. Чат показывает путь в
ai_agent_runs; у папки режим0700, у файла0600. - Макет печати. Собери лист А4 с картой, заголовком, легендой и масштабной линейкой и экспортируй в PDF: PDF открывается, а на модели со зрением проверка после применения смотрит на отрисованный макет.
- История. Хранить разговоры 7 дней удаляет более старые разговоры, но не открытый. Удалить историю и журналы сначала спрашивает, затем очищает и то и другое.