15 KiB
Интеграционные тесты задач — mock-сервер
ARC запускается как обычно (реальные Android-устройства через ADB), но подключается к локальному Flask-моку вместо боевого бэкенда. Мок раздаёт задачи по одной на material, собирает результаты и показывает отчёт в браузере.
1. Требования
| Компонент | macOS | Windows |
|---|---|---|
| Python | brew install python или встроенный |
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
# 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 с живого устройства
# 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]:
[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-сервер
# 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
# macOS (из корня проекта!)
./build_test/ARC
# Windows
build\Release\ARC.exe
При логине мок автоматически ставит задачи:
- 1 × FETCH_PROFILE на каждый материал (если
--typesне ограничивает) - N × FETCH_TRANSACTIONS (случайные из pool)
Задачи раздаются по 1 на material за поллинг — следующая только после получения результата предыдущей. Это предотвращает expire задач в очереди.
Терминал 3 — отчёт
# Браузер с авто-обновлением
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. Ручной инжект задач
# Одна задача
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. Полный цикл с нуля
# 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-уведомления банков
- Сетевые задержки/таймауты