Skip to content

Testing

AceGuru-mjh edited this page Oct 1, 2026 · 4 revisions

测试体系

🛠️ 工程化 · 🏠 首页 › Testing

Home Version Kotlin Modules Tools License

Testing

📑 本页目录

Wiki 版摘要;单一权威文档是仓库的 docs/TESTING.md(理念 / 矩阵 / 替身规范 / FAQ / 测试文件清单,主干现已增至 252 个文件 / ≈4,008 个 @Test 用例)。本文给你"该怎么测、怎么跑、什么必须测"的速查版本。

1. 测试金字塔

        ╱ 仪器测试 ╱  androidTest  ——— 5 个:真机 forkpty/JNI、Ubuntu rootfs 供给
       ╱  (设备) ╱                 (CI 无模拟器:只编译不运行,真机跑通)
      ╱───────────╱
     ╱  JVM 单测  ╱ ———————— 69 个:纯 Kotlin + JUnit4 + runTest,
    ╱  (主力)  ╱                    无网络、无真 LLM、无 Android 运行时
   ╱─────────────╱
  ╱ 静态检查 CI  ╱ ————— 括号平衡 / 工具 ID 唯一性 / 类名重复 / 文件大小预算 /
 ╱  (门禁)    ╱       反模式(反射分发、printStackTrace)/ PRoot 二进制 sha256
╱───────────────╱
  • JVM 单测为主力:core/* 是纯 JVM,天然可测;Android library 模块通过 接口替身 + unitTests.isReturnDefaultValues = true 把被测路径保持在 JVM;
  • 仪器测试留给只有真机才能验证的东西:原生 PTY(forkpty / JNI 桥)、 rootfs 供给(网络下载 + 解包)、PRoot 实进程;
  • 静态检查兜底结构性退化(详见 质量门禁)。

2. 确定性原则(三个"无")

原则 做法
无真实网络 LLM 用 FakeLlmClient(脚本化响应序列),工具用 FakeToolExecutor(注册式返回),GitHub 用离线 fixture
无真实时间依赖 协程测试统一 runTest(虚拟时间,delay 零成本);需要真实挂起点的地方显式 delay(10) 让 collector 先跑
无随机 指纹/哈希类断言只验证性质(确定性、稳定性、区分度),不硬编码具体摘要值

3. 回归锁定原则

Important

每个历史缺陷修复必须伴随一个会失败的回归测试(先红后绿),并在 KDoc 里注明锁定了哪个缺陷。

本项目有大量以此为标记的用例,例如:

  • 旁路引擎跨版本宏回退(BypassExecutionEngineTest);
  • 编排器正文 / 思维链混流(OrchestratorTestSuite 流式语义组);
  • 并行工具调用分片撕裂(tool call fragments with only index merge)。

4. 模块矩阵

模块 类型 文件数 命令
:core:agent-engine JVM 3 套件 ./gradlew :core:agent-engine:test
:core:tool-registry JVM 4 ./gradlew :core:tool-registry:test
:core:llm-adapter JVM 6 ./gradlew :core:llm-adapter:test
:platform:terminal JVM 45 ./gradlew :platform:terminal:testDebugUnitTest
:platform:terminal androidTest 5 ./gradlew :platform:terminal:connectedDebugAndroidTest(真机)
:platform:cs-mem JVM 3 ./gradlew :platform:cs-mem:testDebugUnitTest
:platform:privilege JVM 1 ./gradlew :platform:privilege:testDebugUnitTest
:terminal-emulator JVM 1 ./gradlew :terminal-emulator:test
:app JVM 4 ./gradlew :app:testDebugUnitTest

代表性测试内容与亮点:

模块 锁定什么
core:agent-engine 编排器 6 大类(状态机 / 执行 / 失败传播 / 取消 / 超时 / 事件)+ 韧性套件 + 角色路由黄金用例 + 流式语义回归组
platform:terminal 全域覆盖,含真实 Ubuntu rootfs E2E(真下载 + 真 proot 进程跑 bash / apt);proot 不可用时诚实自跳过高级别场景
core:llm-adapter 多模型运行时:档案校验 / 注册表 / 能力解析 / 错误分类 / 路由
core:tool-registry 流式透传回归(SafeAgentTool 包装器不吞流式)+ DOM 解析
platform:cs-mem 稳定边 ID / 蒸馏参数提纯 / 迁移回退闭环 / 回放偏离防护
app / privilege / terminal-emulator 斜杠文法路由 / 进程流 / VT100 核心

5. 常用命令

# 全量 JVM 测试(约 3–8 分钟)
./gradlew :core:agent-engine:test :core:tool-registry:test \
  :platform:terminal:testDebugUnitTest :platform:cs-mem:testDebugUnitTest \
  --no-daemon -Pkotlin.incremental=false

# 真机仪器测试(需连接设备)
./gradlew :platform:terminal:connectedDebugAndroidTest

# 没有 Android SDK 时的 JVM 类型检查
scripts/compile_terminal_jvm.sh

6. 替身(Fake)规范

替身 用途
FakeLlmClient 脚本化 SSE 序列(文本 / 思维链 / tool_calls 混合),用来锁定流式语义
FakeToolExecutor 按工具 id 注册返回值,避免真实副作用
FakeToolRegistry / StubAgentTool 引擎侧替身,不因接口新增而改动(接口必须有默认实现)
假后端(terminal) LinuxPRootBackend 有 Fake 后端,让逻辑测试不依赖真 ptrace

Note

这也是为什么 工具系统 里"接口新增全部带默认实现"如此重要: 它保证 FakeToolRegistry 一行不改仍能编译 —— 否则每次加字段都要改一堆测试替身。

7. 不允许的事

  • 不允许通过跳过 :core:tool-registry 测试让 CI 变绿;
  • 不允许引入真实网络 / 真实 LLM 调用的单测;
  • 不允许在单测里 Thread.sleep 等真实时间(用 runTest);
  • 不允许把"已知失败"标记为忽略而不说明原因。

8. 相关页面

footer

🏠 返回首页 · 📚 文档索引 · ❓ FAQ · 🔧 故障排查 · 🗺️ 路线图 · 🐛 提 Issue

Android Guru Agent · v1.4.4 · Kotlin 2.0.21 · Compose · PRoot · Room

Clone this wiki locally