AI 测试不是让模型替你断言:用 e2e 混合自然语言与确定性检查
传统端到端测试擅长验证明确条件,却不擅长表达“找到结算页并完成升级”这类目标。反过来,完全交给视觉 Agent 操作又难以稳定复现,也难以判断结果是否真的正确。开源项目 e2e 试图把两种方式放进同一条测试:让 Agent 处理语义动作,再用熟悉的 locator 和断言验证结果。
项目仓库为 tester-army/e2e,采用 Apache-2.0 许可证,面向 Web 与移动应用。README 明确提醒它仍在积极开发、尚未到 1.0,API 和配置可能在小版本间变化。适合评估新型测试流程,不宜不经验证就替换成熟的关键业务回归套件。
自然语言负责“怎么做”,断言负责“是否成功”
项目示例把两类操作并列在同一个测试中:
import { test, expect } from 'e2e';
test('a member upgrades to Pro', async ({ app, agent, screen }) => {
await app.open('/settings/billing');
await agent.act('upgrade the workspace to the Pro plan');
await agent.assert('the invoice preview shows a prorated amount');
await expect(screen.getByRole('status')).toContainText('Pro');
});
agent.act() 描述需要 Agent 完成的语义动作;agent.assert() 检查页面上较难用固定选择器表达的结果;最后的 getByRole 与 toContainText 则是确定性断言。两者不是互相替代:自然语言步骤提高了对复杂界面的适应性,明确断言为关键结果提供可重复的判定。
这类结构尤其适合测试“入口因版本而变化、成功条件却明确”的流程。例如设置页经过改版后,Agent 仍可按目标寻找入口;但最终是否显示 Pro 状态,仍由测试代码明确检查。对金额、权限、订单状态等高风险结果,应尽量保留可机器确定的断言,而不是只让模型判断“看起来完成了”。
录制回放减少重复模型调用,但要理解边界
README 描述的机制是:被后续断言验证过的 Agent 步骤会记录操作;后续运行在应用未变化时可回放这些操作,不必每次都调用模型。没有 Agent 步骤的传统测试则不需要模型。它支持自带订阅、API key 或本地模型,因此团队可按现有模型环境评估成本和数据边界。
回放不是“测试永远稳定”的保证。页面结构、文案、登录状态或测试数据发生变化时,原有操作可能不再适用;回放命中率和失效行为应在自己的应用中测量。建议把模型步骤集中在确实需要语义理解的部分,把导航、数据准备、关键状态验证尽量写成明确代码,并在 CI 中保存失败产物以便复查。
从最小样例开始评估
README 给出的初始化入口是:
npx e2e init
初始化会询问选择 Web 或 Mobile 引擎及模型提供方,并生成配置和示例测试。仓库列出的 Web 引擎通过 Playwright 支持 Chromium、Firefox 和 WebKit;Mobile 引擎覆盖 iOS 与 Android 模拟器/模拟设备。仓库还提供 Vite、Next.js、Astro、Expo、SwiftUI、Jetpack Compose、Kotlin Multiplatform 与 Flutter 等独立示例,适合先找与自身技术栈相近的样例。
更稳妥的试用顺序是:先用公开或测试环境跑一个低风险流程;把自然语言动作与最终断言分开设计;重复运行并观察回放是否符合预期;再验证页面变化、超时和模型不可用时测试如何失败。项目会发送匿名 CLI 使用数据,例如运行了哪些命令、引擎以及失败位置;README 说明不发送测试内容、应用内容或凭据。若不希望发送,可执行 npx e2e telemetry disable,或设置 E2E_TELEMETRY_DISABLED=1。
它适合成为测试金字塔的一层
e2e 的价值不在“把所有测试改写成自然语言”,而在于给传统断言补上语义操作能力。适合探索流程复杂、页面变化频繁、纯选择器测试维护成本高的场景;对于核心业务规则、精确数值和安全敏感操作,确定性断言仍是最终裁判。移动端覆盖是项目提供的能力,但具体设备、平台版本和 CI 环境仍需按官方文档验证。
项目处于 1.0 之前,建议将它作为小范围实验:先比较维护成本、运行时间、失败可诊断性和模型调用情况,再决定是否扩大覆盖。它提供的是一种混合测试范式,而不是无需治理的自动化捷径。