前端开发有个老问题——要快,还要稳。快了容易出 Bug,稳了又跟不上节奏。两边都想顾好,光靠堆人力很难解决。
这篇文章想分享一套我们正在实践的开发方式:AI 辅助开发 + E2E 自动化测试。用一个真实的 SSO 单点登录功能为例,从需求到上线,走一遍完整的流程。
整体流程
把这套方式用一张图表示,大概是这样:- 获取需求
- |
- v
- AI 拆解成任务列表
- |
- v
- AI 编写业务代码
- |
- v
- AI 根据代码提取功能点,生成 E2E 测试用例
- |
- v
- 人工审阅测试用例
- |
- v
- 通知 AI 执行测试,验证结果
复制代码 人在这个流程里的角色,从"全程执行者"变成了"决策者和审核者"。重复性的工作交给 AI,需要判断的地方留给人来把关。
第一步:需求来了,先让 AI 拆任务
产品经理给了这样一段需求:
用户从企业系统跳转过来,URL 里带有加密凭证 encryptedData,我们用这个凭证换取登录 token。如果接口返回用户未绑定手机号,就跳转到绑定页,让用户填写手机号和验证码完成绑定。
把这段话给 AI,让它把需求拆成具体的技术任务。AI 输出的结果大致是:- 1. 调用 SSO 登录接口(pid: 102229),入参 encryptedData
- 2. 登录成功:保存 token,跳转到目标页面(home/flight/hotel 等)
- 3. 接口返回错误码 10811(未绑定):跳转到 /login/sso/bind
- 4. 绑定页:输入手机号,发送验证码(pid: 102024)
- 5. 绑定页:提交手机号 + 验证码(pid: 102304)
- 6. 绑定成功:跳转到目标页面
复制代码 这一步人工要做的事:确认拆解是否合理,有没有漏掉的边界情况。比如 encryptedData 为空怎么处理、网络异常有没有兜底提示。
第二步:AI 编写代码
任务清单确认后,让 AI 按任务写代码。以 sso/index.vue 的登录逻辑为例,AI 生成的代码是这样的:- login() {
- const { encryptedData, to } = this.$route.query
- return request({
- url: '/gateway/api/user',
- data: { encryptedData },
- })
- .then(r => {
- const data = r.data
- if (data) {
- auth.set(data)
- this.doRedirect(to)
- } else {
- this.$dialog.alert({ message: '数据错误' })
- }
- })
- .catch(e => {
- const { code } = get(e, 'data') || {}
- if (code == 10811) {
- return this.$router.push({ path: '/login/sso/bind', query: { to } })
- }
- this.$dialog.alert({ message: e.message || '网络异常' })
- })
- }
复制代码 第三步:AI 分析代码,生成 E2E 测试
代码写完后,把代码给 AI,让它提取功能点并生成 E2E 测试用例。基于上面的登录逻辑,AI 列出的功能点是:
功能点测试用例描述SSO 登录成功模拟接口返回 token,验证页面跳转到 /home未绑定跳转绑定页模拟接口返回 10811,验证跳转到 /login/sso/bind绑定完整流程填手机号、发短信、提交,验证跳转成功未勾选协议不勾选直接提交,验证提示文案出现手机号格式校验输入错误手机号,验证错误提示绑定失败弹窗模拟接口返错,验证弹窗内容跨目标页跳转传入 to=flight,验证最终跳到 /flight生成的测试代码核心设计是用一个 Mock Map 按 pid 拦截接口,测试完全不依赖真实后端:- const mocks = new Map()
- const registerMock = (pid, response) => {
- mocks.set(String(pid), response)
- }
- // 测试:SSO 登录成功后跳首页
- test('should redirect to home on successful SSO login', async ({ page }) => {
- registerMock('102229', {
- res: { hd: { code: 1 }, bd: { data: { token: 'test_token' } } }
- })
- await page.goto('login/sso?encryptedData=valid_token')
- await expect(page).toHaveURL(/.*home/)
- })
- // 测试:返回 10811 跳绑定页
- test('should redirect to binding page on error 10811', async ({ page }) => {
- registerMock('102229', {
- res: { hd: { code: 10811, desc: 'Need binding' }, bd: {} }
- })
- await page.goto('login/sso?encryptedData=needs_bind')
- await expect(page).toHaveURL(/.*login\/sso\/bind/)
- })
复制代码 这里有个值得关注的细节:测试本身就是功能的文字说明。test('should redirect to home on successful SSO login') 这一行,不需要注释,直接读就能理解这个测试在验证什么。
第四步:人工审阅测试用例
这一步是整个流程里最重要的人工环节,不能跳过。
拿到 AI 生成的测试列表,需要从业务角度做审阅,主要看三件事:
覆盖的场景是否合理——AI 生成的 7 个用例基本合理,登录成功、失败、绑定流程都有。
有没有漏掉的场景——比如用户连续点击"发送验证码"怎么处理,encryptedData 为空时的提示是否友好,这些细节 AI 不一定能自动想到。
有没有不必要的用例——有些极端场景测试成本高、价值低,可以先跳过,保持测试套件轻量。
审阅完,给 AI 一个指令:测试用例没问题,帮我跑一下。
第五步:AI 执行测试,给出结果
- npx playwright test tests/e2e/login/sso/sso.spec.js
复制代码 执行结果:- 7 passed (12.3s)
- should redirect to home on successful SSO login
- should redirect to binding page on error 10811
- should complete binding flow successfully
- should show error when agreement is not accepted
- should show error for invalid phone format
- should show dialog on binding failure
- should redirect to flight when to=flight
复制代码 7 个用例全部通过。这意味着这个功能的主要业务流程已经被自动化保护起来了。之后不管谁改这块代码,跑一次测试就能知道有没有改坏。
这套方式的实际收益
问题以前怎么做现在怎么做需求理解偏差开发自己理解,容易漏细节AI 拆任务,人确认,遗漏更少代码覆盖边界靠经验,容易漏错误分支AI 按任务写,边界更完整质量保障靠人工回归测试E2E 自动跑,每次迭代都有保障新人上手要读代码才能懂业务读测试用例就能懂功能最后说一句:这套流程不是要用 AI 代替开发,而是把开发从"写代码"这件事里解放出来一部分,让人可以把精力放在更值得投入的地方——判断需求是否合理、审核逻辑是否正确、决定哪些场景需要覆盖。
来源:程序园用户自行投稿发布,如果侵权,请联系站长删除
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |