端侧计算 × 视觉大模型 × 自学习知识库 的一体化自动化测试 Agent
AutoTest Agent 是一套面向 Android 设备的智能自动化测试平台,由三个核心子项目组成:
| 子项目 | 技术栈 | 职责 |
|---|---|---|
| test_agent | Kotlin · Android AccessibilityService | 设备端 Agent,负责 UI 元素查找、触控注入、屏幕推流、操作录制 |
| cloud_server | Python · FastAPI · asyncio · TCP | 云端控制中枢,负责设备会话管理、AI 推理调度、知识库持久化 |
| test_agent_web | Vue 3 · TypeScript · Vite · Element Plus | Web 管理前端,提供设备实时画面、AI 驾驶舱、知识库管理、脚本录制等可视化功能 |
系统在传统的 AI 纯视觉驱动方案之上,创新性地引入了端侧计算 + 视觉大模型混合推理模式,将单步操作响应从 5-6 秒降至 < 100ms,同时保留 AI 在复杂场景下的自主决策能力。
┌─────────────────────────────────────────────────────────────────────┐
│ test_agent_web (Vue 3 + Vite) │
│ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ ┌──────────┐ │
│ │AI 驾驶舱 │ │ 调试台 │ │脚本录制 │ │设备监控 │ │ 知识库 │ │
│ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ └────┬─────┘ │
│ └──────────┬──┴───────────┴──────────┬──┘ │ │
│ ▼ HTTP + SSE ▼ HTTP ▼ HTTP │
└─────────────────────────────────────────────────────────────────────┘
┌─────────────────────────────────────────────────────────────────────┐
│ cloud_server (Python FastAPI) │
│ │
│ ┌─── HTTP API (4710) ───┐ ┌──── TCP Server (4234) ────┐ │
│ │ /api/devices │ │ TLV 二进制协议 │ │
│ │ /api/task │ │ DeviceSession 管理 │ │
│ │ /api/projects/pages │ │ 视频流解码 (H.264→OpenCV) │ │
│ │ /api/elements │ │ ACK 确认机制 │ │
│ └────────┬───────────────┘ └──────────┬───────────────┘ │
│ ▼ ▼ │
│ ┌─── Intelligence ──────┐ ┌─── Core ──────────────────┐ │
│ │ AIEngine (hybrid) │ │ StabilityDetector (三级) │ │
│ │ ├─ LocalWorker(Ollama)│ │ KnowledgeManager (MySQL) │ │
│ │ └─ CloudWorker(Qwen) │ │ VerificationEngine (4级) │ │
│ │ PromptManager │ │ VideoDecoder (FFmpeg) │ │
│ │ ActionParser │ │ PageMatcher (指纹匹配) │ │
│ └────────────────────────┘ └──────────────────────────┘ │
└───────────────────────────┬──────────────────────────────┬─────────┘
│ TCP (TLV Protocol) │
┌─────────────┴────────────┐ ┌─────────────┴──┐
▼ ▼ ▼ ▼
┌──────────────────┐ ┌──────────────────┐ ┌──────────────────┐
│ 📱 Device 1 │ │ 📱 Device 2 │ │ 📱 Device N │
│ test_agent (APK)│ │ test_agent (APK)│ │ test_agent (APK)│
│ ┌─AgentService─┐│ │ │ │ │
│ │UiAutomation ││ │ │ │ │
│ │TouchEngine ││ │ (同左) │ │ (同左) │
│ │StreamEngine ││ │ │ │ │
│ │RecordEngine ││ │ │ │ │
│ └──────────────┘│ │ │ │ │
└──────────────────┘ └──────────────────┘ └──────────────────┘
test_agent/app/src/main/java/com/malong/auto_test_agent/
├── AgentService.kt # 主服务 (AccessibilityService),指令分发、录制监听
├── AgentBootReceiver.kt # 开机自启广播接收器
├── core/
│ ├── UiAutomationEngine.kt # UI 自动化引擎 (元素查找、反查、WebView 检测)
│ ├── TouchEngine.kt # 触控注入引擎 (InputManager 反射 / Gesture API)
│ ├── StreamEngine.kt # 视频推流引擎 (MediaCodec H.264 硬件编码)
│ └── AccessibilityHelper.kt # 无障碍服务自动开启 (系统签名)
├── network/
│ ├── Protocol.kt # TLV 二进制协议封包/解包
│ ├── AgentClient.kt # TCP 客户端 (自动重连 + 心跳)
│ └── INetworkCallback.kt # 网络事件回调接口
└── infra/
├── DeviceConfig.kt # 设备配置管理 (JSON 文件读写)
└── FileLogger.kt # 文件日志系统
基于 Android AccessibilityService.rootInActiveWindow API,在设备端直接遍历 UI 树查找元素,无需网络往返、无需 AI 推理。
- 多策略查找:
resource-id→text 精确→text 包含→content-desc→bounds→class - 索引定位:支持
text:确定[1]语法定位同名元素中的第 N 个 - Smart Inspect:坐标反查 → 最深叶子节点 → Proximity Search(就近查找) → 语义回溯 → 自动生成最优定位策略
- WebView 黑洞检测:自动识别无子节点或空内容的 WebView,防止陷入无效遍历
- 子树文本合并:对于 FrameLayout 嵌套 TextView 的场景,自动向下搜索文本内容
- 深度保护:最大 50 层遍历深度,返回
DEPTH_EXCEEDED快速失败
双通道触控注入,适配不同权限级别:
- Gesture API(AccessibilityService):标准通道,支持 tap / swipe / long_press
- InputManager 反射(系统签名):高精度通道,支持按键注入 (back / home / keycode)
- Fcitx 广播输入:支持中文和特殊字符文本输入,自动降级到剪贴板方案
基于 MediaCodec + VirtualDisplay 的 Zero-Copy 硬件编码方案:
- 两种推流模式:
HEARTBEAT(1fps 静默监控) /MONITORING(10fps 实时监控) - 自动降帧:60 秒无指令自动回落到 1fps,节省带宽
- Instant Wake:静默期收到新帧立即发送,响应延迟 < 50ms
- Trailing Update:丢帧窗口内的变化通过延迟补帧机制补发
- SPS/PPS 自动拼接:关键帧前自动携带编码参数,支持随时解码
- 事件类型:
TYPE_VIEW_CLICKED/TYPE_VIEW_TEXT_CHANGED/TYPE_VIEW_SCROLLED/TYPE_WINDOW_STATE_CHANGED - 智能语义提取:通过
extractElementInfo()对点击目标进行语义回溯,获取最有意义的父级控件信息 - 多级防抖:Click 300ms / Input 100ms / Scroll 1500ms / Window 500ms
- Click-Induced Scroll 抑制:点击后 500ms 内的滚动事件自动过滤
- 熔断机制:设备放置
/sdcard/disable_agent.txt文件可紧急停止服务
cloud_server/
├── main.py # 服务入口 (HTTP + TCP 并发启动)
├── config.yaml # 全局配置 (端口/AI/视频/数据库)
├── api/
│ ├── server.py # FastAPI HTTP 路由 (~70 个 API)
│ ├── schemas.py # Pydantic 数据模型
│ ├── task_manager.py # 任务管理器 (状态机 + SSE 推送)
│ └── sse.py # Server-Sent Events 实时流
├── core/
│ ├── protocol.py # TLV 协议解析 (与 Android 端对称)
│ ├── network.py # asyncio TCP Server
│ ├── device_session.py # 设备会话 (2500 行核心逻辑)
│ ├── stability_detector.py # 三级画面静止检测器
│ ├── video_decoder.py # H.264 → OpenCV 帧解码
│ ├── knowledge_manager.py # 知识库 CRUD (MySQL)
│ ├── knowledge_engine.py # 知识推理引擎
│ ├── verification_engine.py # 四级断言引擎
│ ├── page_matcher.py # 页面指纹匹配 (Jaccard 相似度)
│ └── database.py # 异步数据库连接池
├── intelligence/
│ ├── engine.py # AI 调度引擎 (Hybrid 模式)
│ ├── base.py # Worker 抽象基类 + Action 枚举
│ ├── openai_worker.py # OpenAI 兼容 Worker (Ollama/Qwen)
│ ├── parser.py # 模型输出结构化解析器
│ ├── prompt_manager.py # Prompt 模板管理
│ └── prompts.py/yaml # System Prompt 定义
└── db/
└── init.sql # MySQL 数据库初始化脚本
每个 TCP 连接对应一个 DeviceSession 实例(~2500 行),是整个系统的中央调度器:
- 视频处理流水线:H.264 解码 → 缩略图生成 → 帧差异计算 → 静止触发 → AI 推理
- ACK 确认机制:
execute_action_sync()发送指令后阻塞等待设备端 ACK,确保操作已执行 - 状态机:
IDLE→ACTION_PENDING→INFERENCING→ 循环 - 死循环检测:dHash 视觉哈希 + 像素差异双重校验,连续 2 帧画面不变注入反思 Prompt
- H.264 环形缓冲:保留最近 300 帧原始编码数据,支持导出最近 30 秒视频证据
- 帧率自适应:任务活跃时 10fps,空闲 60 秒自动降至 1fps
| 级别 | 策略 | 阈值 | 时长 | 触发场景 |
|---|---|---|---|---|
| L1 严格静止 | 连续帧差异 < 1% | strict_threshold=0.01 |
0.5s | 点击后页面加载完成 |
| L2 准静止 | 连续帧差异 < 5% | relaxed_threshold=0.05 |
2.0s | 轻微动画场景 |
| L3 超时兜底 | 超过 T 秒未触发 | — | 5.0s | 持续动画/视频播放 |
另增 空心跳直达 模式:端侧判定静止后发送空包,服务端直接触发下一步推理。
采用 Hybrid 混合调度 架构:
AIEngine
├── LocalWorker (Ollama → gelab-zero-4b-preview) ← 优先
└── CloudWorker (阿里云 DashScope → Qwen3-VL-Plus) ← 队列积压时降级
- 统一 OpenAI 兼容 API:同一套 Worker 代码同时兼容 Ollama 本地推理和阿里云 DashScope
- 多轮历史摘要:任务维度的上下文摘要缓存,避免无限增长的 history
- 结构化输出解析:自定义
parser.py解析模型输出为标准 Action(tap/swipe/input/wait/done) - 坐标归一化:VLM 输出 1000×1000 坐标系 → 设备实际分辨率自动映射
- 可视化证据:每步推理自动保存截图并叠加操作标注(点击十字线/滑动箭头)
L1 Strict → 原生精确匹配 (find_by_id / assert_exists)
L2 Robust → 模糊匹配 + 降级 (text contains)
L3 Healing → VLM 视觉语义校验 + 自动修复选择器 (自愈闭环)
L4 Explore → 目标达成判定 (Activity 检查 + 全局语义)
Healing 自愈闭环:当元素定位失败时,使用 VLM 在截图中搜索语义等价的元素 → Inspect 获取原生属性 → 自动更新数据库中的选择器 → 下次执行时走 Fast Path。
三表结构(MySQL):
| 表 | 说明 |
|---|---|
projects |
项目维度隔离,按 package_name 去重 |
pages |
页面指纹(Activity + 关键词 JSON),支持 Jaccard 相似度匹配 |
elements |
指令→选择器映射,含验证状态、失败计数、AI 修复建议 |
- 页面匹配:基于 Jaccard 相似度的关键词匹配,阈值 0.3
- 元素置信度:
is_verified+fail_count双维度,连续失败触发 Healing
test_agent_web/src/
├── App.vue # 根组件 (顶部导航栏路由)
├── views/
│ ├── Copilot.vue # AI 驾驶舱 (任务下发 + 实时监控)
│ ├── Workbench.vue # 调试台 (实时画面 + Debug 面板)
│ ├── Recorder.vue # 脚本录制 (录制/回放控制)
│ ├── Fleet.vue # 设备监控 (多设备卡片墙)
│ ├── Knowledge.vue # 知识库管理入口
│ ├── Settings.vue # 系统设置
│ └── device-control/ # 多设备批量控制
├── components/
│ ├── DeviceStream.vue # 设备实时画面 (MJPEG 流)
│ ├── DebugPanel.vue # 调试面板 (指令发送 + 反查结果)
│ ├── copilot/
│ │ ├── ChatConsole.vue # AI 对话式任务下发
│ │ ├── LiveMonitor.vue # 任务实时监控 (SSE)
│ │ ├── ActionTimeline.vue # 操作步骤时间线
│ │ └── ActionCard.vue # 单步操作卡片 (截图 + 思考过程)
│ ├── fleet/
│ │ ├── DeviceCard.vue # 设备卡片 (缩略图 + 状态)
│ │ └── StatusBadge.vue # 状态徽章
│ └── knowledge/
│ ├── ProjectSidebar.vue # 项目侧边栏
│ ├── PagePreview.vue # 页面预览 (截图 + XML)
│ ├── ElementTable.vue # 元素表格 (CRUD + 断言配置)
│ ├── AddElementDialog.vue
│ ├── EditProjectDialog.vue
│ └── SavePageDialog.vue
├── api/ # HTTP API 封装
├── stores/ # Pinia 状态管理
├── composables/ # 组合式函数
└── utils/ # 工具函数
| 页面 | 功能 |
|---|---|
| AI 驾驶舱 | 对话式下发自然语言任务,SSE 实时推送执行步骤,可视化操作时间线 |
| 调试台 | 设备实时画面 + 点击反查控件信息 + 手动下发指令 + 推流开关 |
| 脚本录制 | 录制设备操作 → 自动生成 JSON 测试脚本 → 编辑 → 回放 |
| 设备监控 | 卡片墙展示所有设备缩略图、在线状态、屏幕分辨率 |
| 设备控制 | 多设备批量操作(统一点击/滑动/输入),支持变量替换 ({$SN}/{$IP}) |
| 知识库 | 三级导航(项目→页面→元素),元素 CRUD、断言模式配置、自愈记录 |
| Magic (1B: 0xAF) | Type (1B) | Length (4B, Big-Endian) | Payload (NB) |
| Type | 方向 | 说明 |
|---|---|---|
0x01 LOGIN |
C→S | 设备登录 (SN + 屏幕信息 + 版本) |
0x02 AUTH_RESP |
S→C | 认证响应 (含推流参数: fps/bitrate/scale) |
0x03 VIDEO_DATA |
C→S | H.264 视频帧 (关键帧含 SPS/PPS) |
0x04 HEARTBEAT |
C→S | 心跳 (含设备状态: 键盘/包名/Activity) |
0x05 ACTION |
S→C | 操作指令 JSON |
0x06 ACK |
C→S | 指令执行确认 (含查找结果 + 遍历统计) |
0x07 RECORD_EVENT |
C→S | 录制事件 (click/input/scroll) |
0x09 DEVICE_STATE |
C→S | 设备状态变更 (Activity/键盘/推流) |
将确定性操作(元素查找、点击)下沉到设备端执行,响应时间从 5-6 秒降至 < 100ms;仅在需要智能决策时调用 VLM,实现速度与智能的平衡。
不依赖固定等待时间,而是通过帧差异分析精确检测 UI 稳定时刻。IDLE / ACTION_PENDING / INFERENCING 三态切换,Grace Period 机制避免动作执行期间的误触发。
从精确匹配到语义理解的渐进式断言策略。当 UI 元素发生变更(改名/移动),Healing 模式自动调用 VLM 语义搜索 → Inspect 反查 → 更新知识库,实现无人工干预的选择器自修复。
VirtualDisplay → MediaCodec Surface → H.264 NALU → TCP TLV → FFmpeg 解码 → OpenCV 处理,全链路无内存拷贝,端到端延迟 < 200ms。空闲自动降帧,Instant Wake 被动唤醒,兼顾低功耗与低延迟。
利用 AccessibilityEvent 在设备端精确捕获用户操作意图(resource-id / text / contentDesc),上传到服务端后可直接生成可复用的 JSON 测试脚本,无需人工编写。
通过 dHash + 像素差异双重校验检测画面卡死。连续 2 次画面未变化时,向 VLM Prompt 注入 [SYSTEM WARNING] 反思指令,强制 AI 重新规划操作策略。
自主识别无 Accessibility 子树的 WebView 容器(黑洞),上报给服务端后可自动降级为视觉模式操作,避免原生查找永远返回 NotFound。
支持 28+ 台设备同时在线,批量广播操作指令,内置 {$SN} / {$IP} 变量替换,单条指令即可完成多设备差异化配置。
| 组件 | 版本 |
|---|---|
| Android 设备 | API 26+ (Android 8.0+),需系统签名 |
| Python | 3.10+ |
| Node.js | 18+ |
| MySQL | 8.0+ |
| FFmpeg | 5.0+ (系统 PATH) |
mysql -u root -p < cloud_server/db/init.sqlcd cloud_server
pip install -r requirements.txt
# 修改 config.yaml 中的数据库密码和 AI API Key
python main.py服务将启动:
- HTTP API:
http://0.0.0.0:4710 - TCP Server:
0.0.0.0:4234
cd test_agent_web
npm install
npm run dev访问 http://localhost:5173
cd test_agent
# 修改 auto_test_agent_config.json 中的服务器 IP 和端口
# 使用系统签名编译并安装
./gradlew assembleDebug
# 或使用 deploy.bat 自动化部署设备配置文件 (/sdcard/auto_test_agent_config.json):
{
"server_ip": "192.168.1.100",
"server_port": 4234,
"project_key": "my_secret_2026"
}| 接口 | 方法 | 说明 |
|---|---|---|
/api/devices |
GET | 获取所有在线设备 |
/api/devices/{sn}/screenshot |
GET | 获取设备截图 (JPEG) |
/api/devices/{sn}/mjpeg_stream |
GET | 实时 MJPEG 视频流 |
/api/devices/{sn}/config |
POST | 更新设备配置 (推流开关) |
/api/devices/broadcast_action |
POST | 批量下发操作指令 |
/api/task |
POST | 创建 AI 任务 (支持同步/异步) |
/api/task/{id}/stream |
GET | SSE 任务进度推送 |
/api/projects |
GET | 知识库:项目列表 |
/api/projects/{id}/pages |
GET | 知识库:页面列表 |
/api/pages/{id}/elements |
GET/POST | 知识库:元素 CRUD |
/health |
GET | 健康检查 |
支持 30+ 种操作指令,覆盖基础操作、元素查找、文本输入、流控制、录制回放等全场景:
基础操作: tap / swipe / long_press / key / back / home
文本输入: input / text / send_text / clear_input
元素操作: click_element / find_and_click / find_by_id
wait_for_element / assert_exists / get_text / inspect / dump_ui
复合操作: repeat_swipe / repeat_tap
流控制: start_stream / stop_stream / set_stream_mode
录制: start_record / stop_record
内部项目,仅限授权使用。