ARTICLE · 991075
AI 软件开发实战教程(十七):让 AI 像真实用户一样找出页面问题

系列第 17 篇:单元测试全部通过以后,再让 AI 用真实浏览器逐页操作、保留证据、修复问题,并诚实区分自动化与微信真机。
写完功能、跑完测试,最容易产生一种错觉:代码已经完成,页面应该也能用。
K9 开始前,邻行已有 124 个左右的服务和 HTTP 测试,还有注册、发布、候选、交换、确认和删除等 Chromium 旅程。它们能证明关键规则没有明显断裂,却不能回答几个很日常的问题:375px 下菜单还能不能读?默认日期真的显示了吗?点击复制以后用户知道成功没有?分享预览是否遵守设计时的隐私约定?
这一节点使用 gstack 的 QA Skill,把 AI 切换成测试人员和修复人员,而不是继续堆功能。
1. 先按用户路径走,不先看源码猜答案
测试从公开首页开始,再使用两个一次性测试邀请注册虚构司机和乘客。两边分别设置虚构微信号和提醒码,发布同一时间、同一路线的信息。
完整路径是:
注册 → 设置资料 → 发布车找人/人找车
→ 看到可解释候选
→ 交换前确认双方互相披露
→ 各自只看到对方微信号
→ 双方确认同行
→ 占用一个座位
→ 司机关闭信息
→ 已交换联系方式仍可查看
浏览器每到一页都检查可见内容、交互控件、控制台、移动端宽度和敏感资料。截图只使用虚构数据,并保存在 Git 忽略的本地产物目录。
2. 第一个问题不是业务规则,而是五项菜单
在 430px 下,顶部五项菜单刚好能放下;缩到 375px,品牌和菜单却被压成逐字换行。所有链接仍然可点击,所以普通“页面能打开”测试不会失败,但真实用户看到的是一排竖着的字。
修复没有删除导航项,而是在移动端改成底部五等分导航,保持单行和 48px 触控高度;更宽屏幕继续使用顶部导航。回归测试直接读取每个链接的边界,防止以后又被挤高。
3. 原生控件会拒绝后端认为正确的值
发布页的默认日期在后端是一个合法日期对象,模板却把它输出成:
2026/08/02
原生 date 输入只接受 2026-08-02。浏览器因此清空日期框,并在控制台留下格式警告。服务测试没有发现,因为提交时测试主动传入了正确格式。
修复先加一个失败的 HTTP 回归测试,要求响应中出现 ISO 日期,再让日期控件显式使用 %Y-%m-%d。同一页面重新打开后,默认日期可见,警告不再产生。
这个问题很典型:后端类型正确,不代表最终 HTML 符合浏览器契约。
4. “有降级路径”还不够,用户必须看得懂
“复制群文案”原来只调用剪贴板 API。成功时没有反馈,失败时也没有说明。
修复后的行为是:
成功:提示“群文案已复制,可以返回微信粘贴”; 失败:自动选中文案,并提示长按或手动选择; 状态使用 role=status,辅助技术也能读到变化。
联系方式页同样保留只读输入框。自动复制失败并不会堵死流程,用户仍能选择文字、返回微信继续沟通。
5. QA 还发现了视觉和隐私偏差
这轮共发现 6 个问题:
375px 导航逐字换行; 默认日期被原生控件清空; 复制群文案没有结果反馈; 交换、反馈和状态管理按钮退化成浏览器默认小按钮; 交换后的微信号字段没有使用统一表单样式; 分享预览包含当前行程日期、路线和短编号。
最后一个问题尤其值得注意。详情正文和用户主动复制的群文案可以展示大范围路线,但已批准的 UI/UX 文档要求 Open Graph 分享预览只使用通用产品信息。自动测试因此直接扫描 <head>,要求标题固定为“邻行|社区通勤信息板”,并禁止日期、路线和短编号进入预览元数据。
每个问题都按同一节奏处理:保存修复前证据,写失败测试,做最小修复,只暂存相关文件,单独本地提交,再用浏览器保存修复后证据。这样教程保留的不只是“最后看起来不错”,还有问题怎样被发现和证明关闭。
6. 计划中的弱网和错误状态也要真的实现
测试还发现 K9 计划写了弱网、加载和错误状态,但代码里只有空列表。
项目补了一份很小的全局脚本:
离线时持续提示“网络不可用”; 禁用交换、确认、状态修改等提交操作; 恢复网络后要求刷新最新状态,不静默覆盖页面; 表单提交后显示具体“操作中…”状态并防止重复提交。
403、404 和 500 也使用通用中文页面。404 不告诉访问者对象是否曾经存在,500 不展示堆栈,只说明操作可能没有完成以及下一步怎么做。
7. 自动浏览器能证明什么,不能证明什么
最终自动结果是:
make quick:124 个测试通过; make test:124 个通过,1 个 PostgreSQL 专属测试跳过; 分支覆盖率 88.09%; 静态、格式、类型、迁移和 Django 检查通过; Chromium:10 条端到端旅程通过; 深色、减少动态效果、375px、430px、横屏、键盘、离线恢复和全页面敏感扫描通过。
WebKit 没有通过。浏览器文件虽然已经下载,当前主机仍缺少 GTK、GStreamer、WebP、Wayland 等动态库,启动阶段就失败。项目保留了这条环境证据,没有把 Chromium 的绿灯复制成“双浏览器通过”。
微信真机也没有通过。K9 只生成了一份 READY / NOT PASSED 清单,等待真实 iOS 和 Android 微信验证登录保持、剪贴板、手动选择、返回微信、安全区、字体放大和测试群分享预览。
8. 本节点结果
K9 在当前自动环境范围完成,6 个 QA 问题全部修复并回归,健康评分从 95 提升到 100。这里的 100 表示本轮已测分类中没有遗留问题,不表示产品已经生产就绪。
Gate B、Gate C、PostgreSQL 并发、WebKit 环境和真实用户接受度仍然是明确缺口。下一篇进入 K10:准备部署、恢复、脱敏日志、后台进程心跳和受控试用指标,同时继续避免把“有脚本”写成“生产已经验证”。
9. 关键代码与操作
下面是移动布局检查的简化摘录。它不比较截图像素,而是直接验证页面没有水平溢出:
deftest_mobile_layout_does_not_overflow(page, live_server):
for width, height in ((375, 812), (430, 932), (812, 375)):
page.set_viewport_size({"width": width, "height": height})
page.goto(f"{live_server.url}/hall/")
no_overflow = page.evaluate(
"document.documentElement.scrollWidth <= window.innerWidth"
)
assert no_overflow isTrue
验证命令:make e2e-chromium
真实旅程还会检查导航、键盘、深色模式、减少动效、离线状态和敏感信息;微信真机不能由这条命令代替。
10. 本篇验证摘要
两名虚构成员已在 Chromium 中走通注册、发布、候选、交换、确认和关闭流程; 375px、430px、横屏、键盘、深色和减少动效场景已自动检查; 导航、日期格式、复制反馈、按钮样式、字段样式和分享预览六类问题已经修复回归; 离线状态、重复提交防护以及通用 403、404、500 页面已有浏览器证据; WebKit 因当前主机缺少系统依赖未通过,iOS 与 Android 微信真机仍等待人工验收。
11. 附录:相关工具与仓库
11.1 gstack
仓库:garrytan/gstack 地址:https://github.com/garrytan/gstack
11.2 dev-harness
仓库:Dev-Wiki/dev-harness 地址:https://github.com/Dev-Wiki/dev-harness
11.3 UI UX Pro Max Skill
仓库:nextlevelbuilder/ui-ux-pro-max-skill 地址:https://github.com/nextlevelbuilder/ui-ux-pro-max-skill