323 lines
15 KiB
Markdown
323 lines
15 KiB
Markdown
# Интеграционные тесты задач — mock-сервер
|
||
|
||
ARC запускается как обычно (реальные Android-устройства через ADB), но
|
||
подключается к локальному Flask-моку вместо боевого бэкенда. Мок раздаёт
|
||
задачи по одной на material, собирает результаты и показывает отчёт в браузере.
|
||
|
||
---
|
||
|
||
## 1. Требования
|
||
|
||
| Компонент | macOS | Windows |
|
||
|---|---|---|
|
||
| Python | `brew install python` или встроенный | [python.org](https://python.org), галочка «Add to PATH» |
|
||
| Flask | `pip install flask` | `pip install flask` |
|
||
| ADB | `brew install android-platform-tools` | Используется из `tools\adb\windows\` |
|
||
| ARC | `cmake --build build_test` | `cmake --build build --config Release` |
|
||
| Устройства | `adb devices` → `device` | `tools\adb\windows\adb.exe devices` |
|
||
|
||
---
|
||
|
||
## 2. Генерация тестовых данных из БД
|
||
|
||
Перед первым запуском (или при смене устройств/аккаунтов) нужно сгенерировать
|
||
мок-данные из локальной базы. Скрипты читают `config.ini → [db] dbPath`.
|
||
|
||
### 2.1 Стартовые данные: профиль + FETCH_PROFILE
|
||
|
||
```bash
|
||
# macOS (из корня проекта)
|
||
python3 tests/mock_server/gen_mock_data.py
|
||
|
||
# Windows
|
||
python tests\mock_server\gen_mock_data.py
|
||
```
|
||
|
||
Скрипт:
|
||
- Находит `config.ini` в текущей директории (или `build/Release/config.ini`)
|
||
- Открывает БД, читает `bank_profiles` с проверенным PIN-кодом (`pin_code_checked = 'yes'`) и активные `materials`
|
||
- Генерирует:
|
||
- `tests/mock_server/default_profile.json` — профиль для мока
|
||
- `tests/mock_server/scenarios/*_<card>_fetch_profile.json` — по одному на материал (с номером карты в имени)
|
||
- Очищает таблицу `events` в БД
|
||
|
||
Пример вывода:
|
||
```
|
||
config: config.ini
|
||
database: database/app_data.db
|
||
deleted 5 old events
|
||
wrote default_profile.json (3 bank_profiles)
|
||
wrote scenarios/pixel_7_ozon_7919_fetch_profile.json
|
||
wrote scenarios/pixel_7_ozon_9865_fetch_profile.json
|
||
wrote scenarios/pixel_7_dushanbe_city_bank_3258_fetch_profile.json
|
||
wrote scenarios/tecno_km4_ozon_0982_fetch_profile.json
|
||
|
||
Devices (2):
|
||
pixel_7: ozon/7919 (50393cc1…), ozon/9865 (06a1ae15…), dushanbe_city_bank/3258 (36002ac2…)
|
||
tecno_km4: ozon/0982 (7e3a7e4e…)
|
||
```
|
||
|
||
Флаги: `--config C:\path\to\config.ini` — если config не в текущей директории.
|
||
|
||
### 2.2 Пул FETCH_TRANSACTIONS с живого устройства
|
||
|
||
```bash
|
||
# macOS
|
||
python3 tests/mock_server/gen_fetch_transactions.py
|
||
|
||
# Windows
|
||
python tests\mock_server\gen_fetch_transactions.py
|
||
```
|
||
|
||
Скрипт:
|
||
- Читает БД → находит активные материалы
|
||
- Находит подключённые ADB-устройства → матчит по `adb_serial`
|
||
- Показывает меню → выбор материала или `all`
|
||
- Проходит по транзакциям на экране:
|
||
- **Ozon**: парсит заголовки дат (Сегодня/Вчера/dd месяца), определяет дату каждой транзакции по Y-позиции, тапает для получения времени из деталей, скроллит вниз для следующих
|
||
- **Dushanbe**: парсит Выписку, тап в детали, время Dushanbe (UTC+5)
|
||
- Дедупликация по `(amount, created_at)` — одинаковые суммы в один день с разным временем сохраняются как отдельные задачи
|
||
- Сохраняет `scenarios/pool/*_<card>_ft_*.json` с реальными `amount` (в копейках) и `created_at` (UTC)
|
||
- Если мок запущен — сразу инжектит задачи
|
||
|
||
Флаги:
|
||
- `--serial 148697059H000712` — явный ADB-серийник
|
||
- `--kopecks 100` — множитель суммы (по умолчанию 100)
|
||
- `--config path` — путь к config.ini
|
||
|
||
---
|
||
|
||
## 3. Переключение ARC на мок
|
||
|
||
В `config.ini` → `[net]`:
|
||
|
||
```ini
|
||
[net]
|
||
apiBase=http://127.0.0.1:8888
|
||
```
|
||
|
||
Остальные `path*` оставить как есть.
|
||
|
||
> На Windows: `config.ini` обычно лежит рядом с `ARC.exe` в `build\Release\`.
|
||
> Совет: держите копию `config.ini.mock` и `config.ini.prod`.
|
||
|
||
---
|
||
|
||
## 4. Запуск теста
|
||
|
||
### Терминал 1 — mock-сервер
|
||
|
||
```bash
|
||
# macOS — полный цикл (генерация данных + запуск)
|
||
cd tests/mock_server && ./run.sh
|
||
|
||
# macOS — только определённые банки
|
||
cd tests/mock_server && ./run.sh --banks ozon
|
||
|
||
# macOS — только FETCH_TRANSACTIONS (без FETCH_PROFILE)
|
||
cd tests/mock_server && ./run.sh --types FETCH_TRANSACTIONS --banks ozon
|
||
|
||
# macOS — debug режим (auto-reload при изменении кода)
|
||
cd tests/mock_server && ./run.sh --banks ozon --debug
|
||
|
||
# Windows
|
||
cd tests\mock_server
|
||
python mock_server.py --port 8888
|
||
```
|
||
|
||
Флаги `mock_server.py`:
|
||
- `--banks ozon dushanbe_city_bank` — только указанные банки
|
||
- `--types FETCH_TRANSACTIONS` — только указанные типы задач
|
||
- `--ft-per-material 3` — сколько FT на материал при бутстрапе (default 3)
|
||
- `--seed 42` — фиксированный RNG для воспроизводимости
|
||
- `--debug` — Flask debug режим (auto-reload, состояние сохраняется между перезагрузками)
|
||
|
||
При `--debug`:
|
||
- Изменения в `.py` файлах применяются автоматически без перезапуска
|
||
- Состояние задач сохраняется в `.mock_state.json` и восстанавливается при reload
|
||
- Скриншоты сохраняются в `.mock_screenshots/` (переживают reload)
|
||
- При **первом** запуске — чистый старт (events в БД очищаются, state сбрасывается)
|
||
|
||
### Терминал 2 — ARC
|
||
|
||
```bash
|
||
# macOS (из корня проекта!)
|
||
./build_test/ARC
|
||
|
||
# Windows
|
||
build\Release\ARC.exe
|
||
```
|
||
|
||
При логине мок автоматически ставит задачи:
|
||
- 1 × FETCH_PROFILE на каждый материал (если `--types` не ограничивает)
|
||
- N × FETCH_TRANSACTIONS (случайные из pool)
|
||
|
||
Задачи раздаются **по 1 на material за поллинг** — следующая только после
|
||
получения результата предыдущей. Это предотвращает expire задач в очереди.
|
||
|
||
### Терминал 3 — отчёт
|
||
|
||
```bash
|
||
# Браузер с авто-обновлением
|
||
open http://127.0.0.1:8888/_admin/report/html # macOS
|
||
start http://127.0.0.1:8888/_admin/report/html # Windows
|
||
```
|
||
|
||
---
|
||
|
||
## 5. HTML-отчёт
|
||
|
||
`http://127.0.0.1:8888/_admin/report/html` — веб-страница с:
|
||
- Сводкой: всего / выполнено / ошибки / в очереди
|
||
- Группировкой по **устройствам** → **банкам** (Pixel 7 → ozon, dushanbe_city_bank)
|
||
- Для каждой задачи:
|
||
- Task JSON и Result JSON (для успешных — свёрнуты, кнопка "Показать JSON")
|
||
- Ошибки — развёрнуты сразу с красным бейджем
|
||
- Скриншот (если есть) — третья колонка, клик открывает полноэкранный просмотр
|
||
- Кнопка "Копировать" на каждом JSON блоке
|
||
- Цветовой индикацией: зелёный = completed, красный = error, жёлтый = pending
|
||
- Авто-обновлением каждые 2 секунды (состояние свёрнутых/развёрнутых блоков сохраняется)
|
||
|
||
---
|
||
|
||
## 6. Скриншоты
|
||
|
||
Приложение отправляет скриншоты через `POST /monitoring/log` с полем `internal_task_id`.
|
||
Мок-сервер:
|
||
- Сохраняет PNG на диск в `.mock_screenshots/`
|
||
- Привязывает к задаче по `internal_task_id` (точное совпадение с `task_result`)
|
||
- Отображает в отчёте как третью колонку рядом с Task/Result JSON
|
||
- Клик по скриншоту — полноэкранный просмотр (Escape для закрытия)
|
||
|
||
---
|
||
|
||
## 7. Ручной инжект задач
|
||
|
||
```bash
|
||
# Одна задача
|
||
curl -X POST http://127.0.0.1:8888/_admin/inject \
|
||
-H "Content-Type: application/json" \
|
||
--data-binary @scenarios/pixel_7_ozon_7919_fetch_profile.json
|
||
|
||
# Повторный бутстрап (без перезапуска мока)
|
||
curl -X POST http://127.0.0.1:8888/_admin/bootstrap
|
||
|
||
# Сброс (очистка очереди + результатов + скриншотов)
|
||
curl -X POST http://127.0.0.1:8888/_admin/reset
|
||
```
|
||
|
||
---
|
||
|
||
## 8. Админ-эндпойнты мока
|
||
|
||
| Метод | Путь | Назначение |
|
||
|---|---|---|
|
||
| POST | `/_admin/inject` | Положить задачу (или массив) в очередь |
|
||
| POST | `/_admin/bootstrap` | Повторный бутстрап |
|
||
| POST | `/_admin/seed_profile` | Подменить ответ `current_profile` |
|
||
| POST | `/_admin/seed_devices` | Подменить список устройств |
|
||
| GET | `/_admin/report` | JSON: полный отчёт |
|
||
| GET | `/_admin/report/html` | HTML-отчёт с авто-обновлением |
|
||
| GET | `/_admin/report/pending` | Только незавершённые задачи |
|
||
| GET | `/_admin/report/fragment` | JSON-фрагмент для JS-обновления |
|
||
| GET | `/_admin/screenshot/<id>` | PNG скриншот по ID |
|
||
| GET | `/_admin/state` | Счётчики |
|
||
| POST | `/_admin/reset` | Очистить всё, сбросить бутстрап |
|
||
|
||
---
|
||
|
||
## 9. Полный цикл с нуля
|
||
|
||
```bash
|
||
# 1. Установка
|
||
pip install flask
|
||
|
||
# 2. Собрать ARC, запустить с боевым сервером → залогиниться
|
||
# Устройства, профили и материалы появятся в БД
|
||
|
||
# 3. Переключить config.ini на мок
|
||
# [net]
|
||
# apiBase=http://127.0.0.1:8888
|
||
|
||
# 4. Сгенерировать стартовые данные из БД
|
||
python3 tests/mock_server/gen_mock_data.py
|
||
|
||
# 5. Открыть на устройстве банковское приложение → список транзакций
|
||
# Сгенерировать пул задач
|
||
python3 tests/mock_server/gen_fetch_transactions.py
|
||
|
||
# 6. Запустить мок
|
||
cd tests/mock_server && ./run.sh --banks ozon --debug
|
||
|
||
# 7. Запустить ARC (из корня проекта, в отдельном терминале)
|
||
./build_test/ARC
|
||
|
||
# 8. Открыть отчёт
|
||
open http://127.0.0.1:8888/_admin/report/html
|
||
|
||
# 9. Дождаться completed = всего в отчёте
|
||
|
||
# 10. Вернуть config.ini на прод
|
||
```
|
||
|
||
---
|
||
|
||
## 10. Структура файлов
|
||
|
||
```
|
||
tests/mock_server/
|
||
├── mock_server.py # Flask mock-сервер
|
||
├── run.sh # запуск (macOS/Linux): gen_mock_data + mock_server
|
||
├── gen_mock_data.py # генерация default_profile + scenarios из БД
|
||
├── gen_fetch_transactions.py # генерация pool из живого устройства
|
||
├── inject.sh # curl-обёртка для инжекта
|
||
├── default_profile.json # авто-генерированный профиль для мока
|
||
├── README.md # эта инструкция
|
||
├── WINDOWS.md # Windows-специфичные нюансы
|
||
├── .mock_state.json # состояние задач (debug режим, .gitignore)
|
||
├── .mock_screenshots/ # скриншоты с устройств (.gitignore)
|
||
├── scenarios/ # FETCH_PROFILE сценарии
|
||
│ ├── pixel_7_ozon_7919_fetch_profile.json
|
||
│ ├── pixel_7_ozon_9865_fetch_profile.json
|
||
│ └── ...
|
||
└── scenarios/pool/ # пул FETCH_TRANSACTIONS
|
||
├── pixel_7_ozon_7919_01_minus_108_ft_01.json
|
||
├── pixel_7_ozon_9865_01_minus_108_ft_01.json
|
||
├── pixel_7_dushanbe_city_bank_3258_01_plus_5_ft_01.json
|
||
└── ...
|
||
```
|
||
|
||
---
|
||
|
||
## 11. Типовые проблемы
|
||
|
||
| Симптом | Причина | Решение |
|
||
|---|---|---|
|
||
| `config.ini not found` | Скрипт запущен не из корня проекта | `cd` в корень или `--config path` |
|
||
| `No active materials` | Нет профилей с проверенным PIN | Запустить ARC с боевым сервером, добавить PIN |
|
||
| `No ADB devices match` | Устройства не подключены | `adb devices`, проверить USB |
|
||
| `App restarted` ошибки в отчёте | Events остались от прошлого запуска | Мок-сервер чистит events при старте; используйте `run.sh` или запускайте сервер **до** ARC |
|
||
| Задача `pending` навсегда | material в `_in_flight` | `/_admin/reset` и перезапустить ARC |
|
||
| `Transaction not found` | Баг поиска — скролл, видимость кнопок | Анализировать логи (device= в ошибке) |
|
||
| `Page load error` | Ozon WebView не загрузился | Проблема интернета/устройства, таймаут 5 мин |
|
||
| Скриншот не привязан | Нет `internal_task_id` | Обновить ARC (фикс в EventHandler.cpp) |
|
||
| Pool material_id не совпадает | БД обновилась, pool устарел | Перегенерировать pool или обновить material_id в файлах |
|
||
| Порт занят | Другой процесс на 8888 | `--port 9999` + поменять `apiBase` |
|
||
|
||
---
|
||
|
||
## 12. Что мок эмулирует и что нет
|
||
|
||
**Эмулирует:**
|
||
- Авторизацию (login/refresh)
|
||
- Синхронизацию профилей (current_profile, bank_profile CRUD)
|
||
- Выдачу задач (get_tasks) с in-flight контролем
|
||
- Приём результатов (task_result) с `internal_task_id`
|
||
- Приём скриншотов (monitoring/log) с привязкой к задачам
|
||
- Управление устройствами и материалами (toggle)
|
||
|
||
**Не эмулирует:**
|
||
- Валидацию тел запросов
|
||
- Webhook-уведомления банков
|
||
- Сетевые задержки/таймауты
|