云计算百科
云计算领域专业知识百科平台

SimulatedAdb 揭秘:Shield Optimizer 如何模拟整个 ADB 服务器做端到端测试

【免费下载链接】shield_optimizer

项目地址:
https://gitcode.com/gh_mirrors/sh/shield_optimizer

点击查看 免费下载

Shield Optimizer(现名 ATV Optimizer)是一款用于 Android TV 设备的开源优化工具:禁用预装垃圾应用、切换启动器、侧载 APK、调整 HDMI-CEC 与帧率匹配。这类工具每次操作都会真正写入系统,所以"改坏了怎么办"是核心问题。答案就藏在它的 E2E(end-to-end,端到端)测试里:一个名叫 SimulatedAdb 的测试组件,在内存中完整模拟出 ADB 服务器以及它背后的每一台"电视",让真实界面与真实业务代码在一个虚拟设备世界里完整跑通全流程。

Shield Optimizer 端到端测试驱动的 ATV Optimizer 桌面应用完整操作演示

1. 为什么需要一台"假电视" 📺

对这类工具做端到端测试,通常有两条路,但都不理想:

方案问题
连真电视测试 不稳定、不可重复,CI 里根本跑不了
用简单的打桩 mock 打桩太浅,只能对字符串做子串匹配,抓不到后端逻辑的 bug

项目里其实还有一个 Demo 模式(v2/src/lib/demo-mock.ts),它用 TypeScript 回答命令,适合做演示截图,但无法捕捉后端 bug。SimulatedAdb 就是为此而生的"重武器":它不是简单的字符串匹配,而是有状态的模拟器——禁用一个应用后,pm list packages -e 的输出就真的少了它;切换 Home 后,Home 键的行为就真的变了。

Shield Optimizer 端到端测试中的设备扫描界面:在模拟网络上发现电视设备

2. 测试管线:只换 ADB 驱动,其余全是真的

E2E 管线的设计原则是"The real app, minus the TV"(真实的应用,减去电视):

  • 真实前端:Playwright 驱动真实的 Svelte 界面;
  • 真实后端:每一条界面命令都走 e2e_server.rs 中注册的手动分发——与桌面应用注册的是同一张命令表,参数名、反序列化、状态、每个命令函数体都原样执行;
  • 唯一被替换的,是 ADB 驱动层:换成 SimulatedAdb。

也就是说,从你点击按钮到业务逻辑判定,全都是真代码,只有"电视那头"是模拟的。完整说明见 v2/e2e/README.md。

Shield Optimizer 端到端测试:优化流程在模拟设备上真实执行的进度界面

3. SimulatedAdb 到底模拟了什么?

核心实现位于 v2/crates/core/src/adb/sim/,它实现与真实驱动相同的 AdbDriver 接口,因此在命令层看来与真机毫无区别。

3.1 服务器侧:一台"活"的 adb server

world.rs 中的 World 模型维护着整个虚拟世界:

  • 传输(Transports):每台设备有 device / unauthorized / offline 三种状态,就像真机的 adb devices 输出一样;
  • mDNS 服务:模拟 Android 11+ 无线调试的随机端口广播;
  • 配对与自动重连:设备断开后,如果它已配对并在广播,"adb server" 会像真实行为一样把它重新拉回来。

3.2 设备侧:一台"有脾气"的 Android TV

device.rs 为每台模拟设备维护应用列表(启用/禁用/卸载三个状态)、系统设置、系统属性,以及最复杂的 Home 策略。它内置了 4 种策略(HomePolicy),分别对应真实世界中的不同"坑":

  • 普通偏好策略(用户选了哪个启动器就听谁的);
  • Shield / Android 11:系统预装启动器无视你的选择,set-home-activity 回 "Success" 但 Home 纹丝不动;
  • Google TV 的 Setup Wraith:以高优先级抢走 Home 键,除非把它一起禁用。

这些策略全部来自真实用户报障(如 issue #122),模拟器让这类"灵异现象"变成了可复现的回归测试,例如 42-setup-wraith.mjs 这个场景。

3.3 内置一个"会读命令"的 shell 解释器

应用从不发单条命令,而是发送用 ;、子 shell、2>/dev/null、$? 状态标记拼起来的批量读取串。如果只是按子串匹配,模拟器会"恰好同意"应用发来的任何内容,测试就失去意义。因此 shell.rs 实现了一个小型 POSIX 风格解释器:逐条解析并执行每个简单命令,跟踪 $?,并像 sh 一样让最后一条命令的状态成为整个调用的退出码。

4. 设备档案:来自真机,但绝对干净 🧼

模拟器的"底料"是真实设备的只读捕获,存放于 v2/crates/core/tests/fixtures/devices/(目前已收录 shield-tv-pro 与 pixel-10-pro 两套档案)。捕获脚本 capture-device.sh 只执行只读命令(getprop、pm list packages 等),并且写入前强制脱敏:

  • IP 地址映射到文档保留段 192.0.2.0/24;
  • MAC、SSID、邮箱、设备名全部替换;
  • 脚本最后会再检查一遍,发现残留隐私即失败。

捕获中没有的输出(如 dumpsys display)则由 profile.rs 用通用模板合成,保证每个界面都有"形似真机"的数据可解析。

5. 故障注入:把"倒霉现场"变成可复现的测试 🧨

faults.rs 定义了一套故障规则,按子串匹配某条设备命令(或整个 adb … 参数),支持 5 种效果:

效果行为
fail 返回错误输出与退出码,状态不变
ignore 回复"成功"但什么都不改(模拟"接受但忽略"的设置器)
output 直接替换输出
timeout 整个 adb 调用超时(与桌面驱动的 30 秒超时一致)
delay 延迟 N 毫秒再正常回答

还可以用 times 限制触发次数、用 after 让前 N 次请求正常通过、用 serial 把规则限定在某台设备上。从此"偶发超时""设备装傻"不再是玄学,而是一条声明式的测试数据。

6. 覆盖盲区必须"大声失败" 🔊

模拟器对没有建模的命令不会假装成功,而是返回 simulated device has no handler for: <command>(退出码 127),并记录到 state().gaps。每个场景跑完后,运行器都会打印所有 gaps,视觉冒烟测试遇到 gap 直接判失败——保证"覆盖率洞"可见,而不是被悄悄吞掉。

7. 录制回放:把真实会话喂回模拟器 ⏪

桌面应用开启 Debug 日志后,会把每次 adb 调用连同 UI 面包屑(路由、标签页、按钮,绝不记录输入内容)写成 JSONL 会话文件。基于 replay.rs 的回放能力:

  • npm run e2e:replay <会话文件> 可用当时设备说过的原话逐条回答回放,并把界面操作一步步驱动出来,逐步截图;
  • 结束时报告分歧:unrecorded(新版发出了录制里没见过的命令)、out_of_order(顺序变了)、not_replayed(录了却没用上),行为变化一目了然;
  • 还可以用 e2e_server profile-from-session 把一次真实会话直接炼成新的设备档案,脱敏规则与真机捕获完全一致。

8. 自己动手跑一遍

SimulatedAdb 只在测试与 test-support 特性下编译,永远不会出现在发布版本里。运行方式(在 v2 目录下):

npx playwright install chromium # 只需一次
npm run e2e # 跑全部场景
npm run e2e — launcher snapshot # 按名称过滤

运行器 harness.mjs 会自动构建 E2E 服务器、在空闲端口启动 Vite、以无头 Chromium 执行 scenarios/ 下的全部场景,每一步都截图存档到 e2e/artifacts/。CI 在每次发版前运行它,失败时上传截图供审查。


小结:SimulatedAdb 用一台"有记忆、会断线、能装傻"的虚拟 ADB 服务器,把真电视上最难复现的坑全部搬进了测试环境。对工具作者来说,它是敢对系统做修改的底气;对开源贡献者来说,读 v2/e2e/README.md 和场景代码,就是学习"如何给系统级工具写可靠测试"的完整范本。

赞

分享

【免费下载链接】shield_optimizer

项目地址:
https://gitcode.com/gh_mirrors/sh/shield_optimizer

点击查看 免费下载

上一篇:
UE4SS完全指南:5步掌握虚幻引擎LUA脚本注入与游戏Mod开发

下一篇:
3分钟快速上手MHY_Scanner:米哈游游戏智能扫码登录终极指南

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

赞(0)
未经允许不得转载:网硕互联帮助中心 » SimulatedAdb 揭秘:Shield Optimizer 如何模拟整个 ADB 服务器做端到端测试
分享到: 更多 (0)

评论 抢沙发

评论前必须登录!