13 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 |
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) - Открывает БД, читает активные
devices → bank_profiles → materials - Генерирует:
tests/mock_server/default_profile.json— профиль для мокаtests/mock_server/scenarios/*_fetch_profile.json— по одному на материалtests/mock_server/scenarios/*_fetch_transactions.json— для ручных прогонов
Пример вывода:
config: config.ini
database: database/app_data.db
wrote default_profile.json (3 bank_profiles)
wrote scenarios/pixel_7_ozon_fetch_profile.json
wrote scenarios/pixel_7_dushanbe_city_bank_fetch_profile.json
wrote scenarios/tecno_km4_ozon_fetch_profile.json
Devices (2):
pixel_7: ozon (30bc106c…), dushanbe_city_bank (61d967d1…)
tecno_km4: ozon (49001bb5…)
Флаги: --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 - Показывает меню:
Available materials (3): 1. Pixel 7 / ozon / Галина Терехина (material 30bc106c…) 2. Pixel 7 / dushanbe_city_bank / Мехрубон (material 61d967d1…) 3. TECNO KM4 / ozon / Владислав Касаткин (material 49001bb5…) Pick [1-3] or 'all': - После выбора просит открыть список транзакций на устройстве → Enter
- Проходит по каждой транзакции: тап → дамп деталей → назад (перед каждым тапом проверяет, что мы на списке)
- Сохраняет
scenarios/pool/*_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
# Windows
cd tests\mock_server
python mock_server.py --port 8888
Логи в консоли:
[mock] state cleared — starting fresh
[mock] loaded default_profile.json: 3 bank_profiles, 3 materials
[mock] loaded pool: 19 FETCH_TRANSACTIONS across 3 materials
* Running on http://127.0.0.1:8888
Флаги:
--ft-per-material 3— сколько FT на материал при бутстрапе (default 3)--seed 42— фиксированный RNG для воспроизводимости
Терминал 2 — ARC
# macOS
./build/ARC
# Windows
build\Release\ARC.exe
При логине мок автоматически ставит задачи:
- 1 × FETCH_PROFILE на каждый материал
- 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
# Счётчики в реальном времени
watch -n 2 'curl -s http://127.0.0.1:8888/_admin/state' # macOS
# Windows (PowerShell)
while ($true) { cls; (iwr http://127.0.0.1:8888/_admin/state).Content; sleep 2 }
5. HTML-отчёт
http://127.0.0.1:8888/_admin/report/html — веб-страница с:
- Сводкой: всего / выполнено / в очереди
- Группировкой по устройствам (Pixel 7, TECNO KM4, …)
- Для каждой задачи: Task JSON слева ↔ Result JSON справа
- Цветовой индикацией: зелёный = completed, жёлтый = pending, красный = error
- Авто-обновлением каждые 2 секунды (без сброса скролла)
Также доступен JSON:
curl -s http://127.0.0.1:8888/_admin/report | jq # полный
curl -s http://127.0.0.1:8888/_admin/report/pending | jq # только pending
6. Ручной инжект задач
# Одна задача
./inject.sh scenarios/pixel_7_ozon_fetch_profile.json # macOS
curl -X POST http://127.0.0.1:8888/_admin/inject ^ # Windows
-H "Content-Type: application/json" ^
--data-binary @scenarios\pixel_7_ozon_fetch_profile.json
# N случайных из пула
python inject_random.py --count 5
# Повторный бутстрап (без перезапуска мока)
curl -X POST http://127.0.0.1:8888/_admin/bootstrap
# Сброс (очистка очереди + результатов + in-flight)
curl -X POST http://127.0.0.1:8888/_admin/reset
7. Админ-эндпойнты мока
| Метод | Путь | Назначение |
|---|---|---|
| POST | /_admin/inject |
Положить задачу (или массив) в очередь |
| POST | /_admin/bootstrap |
Повторный бутстрап (1 FP + N FT на material) |
| 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/state |
Счётчики |
| POST | /_admin/reset |
Очистить всё, сбросить бутстрап |
8. Полный цикл с нуля (новая машина / новые устройства)
# 1. Установка
pip install flask
# 2. Собрать ARC, запустить с боевым сервером → залогиниться → устройства,
# банковские профили и материалы появятся в БД
# 3. Переключить config.ini на мок
# [net]
# apiBase=http://127.0.0.1:8888
# 4. Сгенерировать стартовые данные из БД
python tests/mock_server/gen_mock_data.py
# 5. Открыть на устройстве банковское приложение → список транзакций
# Сгенерировать пул задач
python tests/mock_server/gen_fetch_transactions.py
# 6. Запустить мок
cd tests/mock_server && python mock_server.py --port 8888
# 7. Запустить ARC (в отдельном терминале)
./build/ARC # macOS
build\Release\ARC.exe # Windows
# 8. Открыть отчёт
open http://127.0.0.1:8888/_admin/report/html
# 9. Дождаться completed = всего в отчёте
# 10. Вернуть config.ini на прод
# [net]
# apiBase=http://93.183.75.134:8005
9. Структура файлов
tests/mock_server/
├── mock_server.py # Flask mock-сервер
├── run.sh # запуск (macOS/Linux)
├── gen_mock_data.py # генерация default_profile + scenarios из БД
├── gen_fetch_transactions.py # генерация pool из живого устройства
├── inject.sh # curl-обёртка для инжекта
├── inject_random.py # рандомный инжект из pool
├── default_profile.json # авто-генерированный профиль для мока
├── seed_profile.example.json # пример ручного засева
├── README.md # эта инструкция
├── WINDOWS.md # Windows-специфичные нюансы
├── scenarios/ # одиночные задачи (FETCH_PROFILE / FT с пустым body)
│ ├── pixel_7_ozon_fetch_profile.json
│ ├── pixel_7_ozon_fetch_transactions.json
│ ├── tecno_km4_ozon_fetch_profile.json
│ └── ...
├── scenarios/pool/ # пул FETCH_TRANSACTIONS с реальными amount + created_at
│ ├── pixel7_ozon_ft_01_evgeny_plus_100.json
│ ├── tecno_km4_ozon_ft_01_galina_plus_100.json
│ └── ...
└── fixtures/ # XML/PNG дампы экранов (справочно)
├── tecno_ozon/
├── pixel7_ozon/
└── pixel7_dushanbe/
10. Типовые проблемы
| Симптом | Причина | Решение |
|---|---|---|
config.ini not found |
Скрипт запущен не из корня проекта | cd в корень или --config path |
No active materials |
БД пустая или профили не active | Запустить ARC с боевым сервером, залогиниться |
No ADB devices match |
Устройства не подключены или serial не совпадает | adb devices, проверить USB |
Задача pending навсегда |
material в in-flight (результат не пришёл) | /_admin/reset и перезапустить ARC |
Task expired: waited Ns |
Предыдущая задача выполнялась >5 мин | Мок отдаёт по 1 задаче — это уже фикс; убедиться, что maxScrolls разумный |
Transaction not found |
Транзакции на устройстве не совпадают с pool | Перегенерировать: gen_fetch_transactions.py |
Cancelled: replaced |
Норма для FETCH_PROFILE — дедупликация по device+bank | Не баг |
| Мок не получает результат | sendTaskError шёл в monitoring вместо task_result |
Обновить ARC (фикс в EventHandler.cpp) |
| Кракозябры в консоли (Win) | Кодировка | chcp 65001 перед запуском |
| Порт занят | Другой процесс на 8888 | --port 9999 + поменять apiBase |
11. Что мок НЕ эмулирует
- Валидацию тел запросов (всё
{success: true}) - Хранение скриншотов
- Webhook-уведомления банков
- Сетевые задержки/таймауты