midscene-android 工程说明

midscene-android 是一个 Python 包,将 Midscene.js 的 Android AI 自动化能力桥接到 Python 测试体系。用户通过 MidsceneAgent 调用能力,无需自行安装 Node.js,也无需维护 UI 选择器。

PyPI:https://pypi.org/project/midscene-android/

下载安装:

pip install midscene-android

源码:github.com midscene-python 或者 gitee.com midscene-python


背景与目标

Android UI 自动化通常依赖 resource-id、xpath 等固定选择器,页面变更后脚本维护成本较高。Midscene 提供基于视觉模型和自然语言的自动化能力,但核心实现位于 Node 生态。

本项目的目标:

  • 在 Python / pytest 测试体系中接入 Midscene Android 能力,无需迁移技术栈
  • 提供同步 Python API,贴近测试代码写法
  • 用户无需预装 Node.js;首次运行时自动准备运行时环境
  • 覆盖安装、缓存、异常处理、测试与发布等工程环节

架构

PyTest Python Script

MidsceneAgent

JsonRpc Local Loopback

NodeServiceManager

service.js

@midscene/android

ADB

AndroidDevice

VisionModelAPI

组件职责:

组件 职责
MidsceneAgent Python 侧入口,提供 AI 操作与设备控制 API
NodeServiceManager Node 子进程单例管理,JSON-RPC 通信
service.js Node 微服务,代理 Midscene Android 与 ADB
node_bootstrap 首次运行时下载 Node/npm 并写入本地缓存

设计选择:

  • Python 不重写 Midscene 能力,通过本地 JSON-RPC 桥接 Node 服务
  • 多个 MidsceneAgent 共享同一 Node 进程,通过 sessionId 隔离
  • Python 进程退出时,Node 子进程由 atexit 自动清理

API 设计

API 按测试场景分层,而非直接暴露底层 RPC 方法:

类型 方法 适用场景
复合操作 ai_action() 描述多步业务目标
单步操作 ai_tap()ai_input()ai_scroll() 关键路径的稳定步骤
断言与查询 ai_assert()ai_query()ai_boolean() 基于 UI 语义的验证
设备控制 launch_app()get_screenshot()run_adb_shell() 应用管理与调试

基本用法:

from midscene_android import MidsceneAgent

with MidsceneAgent("emulator-5556") as agent:
    agent.ai_tap("登录按钮")
    agent.ai_input("用户名输入框", "testuser")
    agent.ai_assert("当前页面是用户首页")

pytest 集成:

import pytest
from midscene_android import MidsceneAgent


@pytest.fixture
def agent():
    ag = MidsceneAgent("emulator-5556")
    yield ag
    ag.destroy()


def test_login(agent: MidsceneAgent):
    agent.ai_input("用户名输入框", "testuser")
    agent.ai_tap("登录按钮")
    agent.ai_assert("登录成功,显示用户首页")

配置通过环境变量或 .env 提供(MIDSCENE_MODEL_BASE_URLMIDSCENE_MODEL_API_KEYMIDSCENE_MODEL_NAME 等),由 MidsceneConfig 统一加载与校验。


运行时 Node Bootstrap

早期方案将 Node 二进制与 npm 打入 wheel,但受 PyPI 单文件 100MB 限制及多平台体积影响,改为运行时自举:

  1. pip install midscene-android — 包内仅含 Python 代码与 service.js 源码
  2. 首次调用 MidsceneAgent — 触发 node_bootstrap.ensure_node_runtime()
  3. 检查 ~/.midscene_android/node_runtime/ 缓存,缺失则从 nodejs.org 下载
  4. 执行 npm install @midscene/android~/.midscene_android/node_service/
  5. 启动 Node RPC 服务;后续运行复用缓存

版本变更时通过缓存元数据(VERSION_FILENPM_DONE_FLAG)触发依赖重装。


可靠性

问题 处理方式
配置缺失 MidsceneConfigError,明确提示缺少的环境变量
RPC 传输错误 统一包装为 MidsceneNodeServiceError,不裸抛 requests 异常
Node 进程崩溃 自动重启一次并重试
stdout 管道阻塞 独立线程持续消费 Node 子进程 stdout,避免长会话卡死
日志文件膨胀 Node 服务日志 5MB 上限并自动轮转

测试分层

测试按依赖程度分为三层,避免全部用例依赖真实设备:

层级 内容 是否需要设备
Level 1 缓存、版本管理、bootstrap 逻辑
Level 2 Node 服务启动、Agent 初始化、RPC 链路
Level 3 完整 AI 操作 是(pytest.mark.device

CI 默认执行 -m "not device",仅跑 Level 1 和 Level 2。


项目结构(核心模块)

src/midscene_android/
├── midscene_agent.py    # Python 侧 API 入口
├── node_service.py      # Node 子进程管理与 JSON-RPC
├── node_bootstrap.py    # 运行时 Node/npm 下载与缓存
├── runtime.py           # 缓存路径与版本管理
├── config.py            # 配置加载与校验
└── _node_driver/service/
    ├── service.js       # Node 微服务
    └── package.json

总结

midscene-android 是一个 Python/Node 混合桥接工程:Python 侧提供测试友好的同步 API,Node 侧复用 Midscene.js 能力,运行时 bootstrap 解决 Node 环境分发问题。主要工程工作集中在 RPC 通信、缓存管理、异常语义、测试分层与 PyPI 发布链路。

更多推荐