前言
最近准备重新设计公司的自动化测试框架。
一开始,我的目标其实很简单:
能不能让 AI 完全替代测试人员?
后来越研究越发现,这条路并没有想象中那么简单。
这篇文章主要记录整个思考过程,而不是介绍某个具体项目。
最初的设想
最开始,我想的是:
AI
↓
自己规划测试流程
↓
点击所有按钮
↓
分析结果
↓
生成报告理论上,大模型已经能够:
- 理解界面
- 点击按钮
- 阅读文本
- 判断结果
似乎已经可以完成整个自动化测试。
但是深入调研以后,我发现真正的问题并不是:
AI 能不能做到。
而是:
AI 能不能稳定做到。
为什么放弃 AI 全流程驱动?
最大的几个问题:
1. Prompt 太脆弱
不同的软件版本
不同的界面
不同的弹窗
都会影响最终效果。
为了提升稳定性,需要不断调整 Prompt。
最终维护成本非常高。
2. AI 不适合确定性验证
例如:
金额计算
属性计算
优惠券叠加
编码参数
…
这些结果必须:
100%
正确。
99% 的准确率其实等于不能使用。
这些场景应该交给:
- 单元测试
- 集成测试
- Assert
而不是 AI。
3. AI 自己规划流程容易失控
例如:
今天:
打开软件
↓
录像
↓
关闭软件明天:
AI 可能决定:
打开软件
↓
修改属性
↓
录像
↓
打开菜单
↓
关闭软件流程越来越不可预测。
Bug 很难复现。
日志也很难分析。
一个重要的转折
后来看到了一些 AI 自动化测试方案(例如 KUITest)。
让我意识到:
AI 真正擅长的是:
泛化。
不是:
控制流程。
于是整个思路开始改变。
AI 应该负责什么?
后来我把职责重新划分。
AI:
负责:
- 理解界面
- 提供扰动
- 判断视觉异常
- 分析测试报告
- 推荐新的测试 Case
传统自动化:
负责:
- 流程执行
- 点击
- Assert
- 数据验证
- 属性验证
整个职责开始变成:
flowchart LR
goal["可靠的自动化测试"]
subgraph ai["AI · 负责泛化"]
direction TB
a1["理解界面"]
a2["提供扰动"]
a3["判断视觉异常"]
a4["分析报告与推荐 Case"]
end
subgraph deterministic["传统自动化 · 负责确定性"]
direction TB
d1["执行固定流程"]
d2["点击与读取属性"]
d3["数据验证与 Assert"]
d4["输出可复现结果"]
end
ai --> goal
deterministic --> goal
自动化测试真正的目标
以前我一直认为:
自动化测试:
就是:
模拟人的操作。
后来发现不是。
真正的目标其实是:
构建一条可以不断重复执行的验证链路。
所以我重新定义了一条测试链:
flowchart LR
backend["Backend<br/>PASS"] --> service["Service / Feeder<br/>PASS"]
service --> client["Client<br/>FAIL"]
client --> ui["UI<br/>FAIL"]
classDef passed fill:#dff4dd,stroke:#171c24,color:#171c24,stroke-width:2px
classDef failed fill:#ffd9d4,stroke:#171c24,color:#171c24,stroke-width:2px
class backend,service passed
class client,ui failed
每一层都应该能够独立观察。
失败的时候,不再只告诉你一个 FAIL,而是同时标出每一层的状态。
这样开发人员几乎可以立即定位问题。
自动化测试应该如何分层?
最终我把整个系统拆成了六层。
flowchart TB
testCase["06 · Case<br/>组合业务测试流程"]
ui["05 · UI Adapter<br/>读取界面状态"]
backend["04 · Backend Adapter<br/>调用 Backend DLL 与记录 Trace"]
observer["03 · Observer<br/>只观察系统状态"]
windows["02 · Windows 能力<br/>Process / Service / Shortcut / File"]
core["01 · Core<br/>Runner / Step / Context / Timeline"]
testCase --> ui
testCase --> backend
testCase --> observer
ui --> windows
backend --> windows
observer --> windows
windows --> core
第一层:Core
负责:
- TestRunner
- Step
- Context
- Timeline
这里不关心任何业务。
第二层:Windows 能力
封装:
- Process
- Service
- Shortcut
- File
所有和 Windows 相关的能力。
第三层:Observer
负责观察系统状态。
例如:
- service_status.json
- camera_snapshot.json
Observer 永远不主动控制系统。
只负责观察。
第四层:Backend Adapter
封装 Backend DLL。
提供:
- Discover
- Open
- Close
- Property
- Capture
所有调用都会记录 Trace。
第五层:UI Adapter
封装:
UI Automation。
这里只负责:
读取。
而不是业务。
第六层:Case
真正的测试流程。
例如:
CheckService
↓
Launch AdminConsole
↓
Observer 获取 Camera
↓
UI 获取 Camera
↓
Compare
↓
Generate ReportCase 不直接调用底层。
而是组合已有能力。
为什么要这样分层?
因为真正需要复用的不是:
代码。
而是:
能力。
例如:
今天完成:
LaunchProcess()以后:
任何 Case 都可以使用。
今天完成:
ReadCameraList()以后:
所有测试流程都能直接调用。
整个系统会越来越像积木。
而不是越来越复杂。
多 Agent 开发
整个项目后面采用了多 Agent 并行开发。
每个 Agent:
只负责一个模块。
例如:
Agent A
↓
Core
----------------
Agent B
↓
Windows
----------------
Agent C
↓
Observer
----------------
Agent D
↓
Backend Adapter
----------------
Agent E
↓
UIA
----------------
Agent F
↓
Case第二天回来以后。
我不会先 Review 代码。
而是:
Review:
能力。
例如:
今天:
新增了:
- 启动程序
- 检查 Service
- Observer
- Camera Discovery
只有这些能力全部能够独立验证。
才开始进入下一阶段。
我的收获
这次最大的改变其实不是:
设计了一套自动化测试。
而是重新理解了 AI。
AI 不应该替代整个流程。
而应该负责:
那些传统自动化最不擅长的部分。
而:
确定性、
稳定性、
可复现、
可定位,
依然应该交给传统自动化。
最终形成:
AI
负责:
泛化。
传统自动化
负责:
确定性。我认为,这种职责划分,才是真正适合工程项目的 AI 自动化测试方向。
后续计划
目前 V1 的目标非常明确:
- 完成基础框架
- 建立 Observer
- 打通 Backend → Client → UI 链路
- 实现第一条可重复执行的自动化 Case
等这一版稳定以后,再逐步引入:
- AI 扰动生成
- AI 日志分析
- AI 测试建议
- AI 回归策略优化
而不是一开始就把 AI 放到整个测试流程的中心。