
去年有个做 QA 的朋友跟我算过一笔账。
他们团队每周发 5 次版本,每次回归测试手动跑一遍要 3 小时。一周下来,15 个小时全耗在“打开测试环境、登录、钻三层菜单、填表单、点提交、等加载、查表格”这些动作上。更难受的是,人一重复就容易走神,漏测、误判时不时冒出来,版本上线反而被拖慢。
所有人都默认“这就是 QA 的工作”。他没忍。200 行 Python + Playwright,把 3 小时压到了 4 分钟,零差错。
我把他那 200 行拆了一遍。结论是:不是代码写得少,是每一行都花在了刀刃上。
一、先别写代码,先把“确定性”从流程里挤出来他做的第一件事不是打开编辑器,是把 QA 手动流程拆到不能再拆。
原来的流程里混着很多“只有人才能判断”的东西——这个提示文案语气对不对、那个加载动画是不是太慢。这些不适合自动化,硬塞进去只会让脚本越来越脆。
他把流程过了一遍筛子,只留下确定性动作:登录、建号、导航到账单页、提交一笔模拟购买、验证发票生成、确认后台任务完成。同时删掉了两个冗余的手动检查步骤,流程从“看起来完整”变成了“真正可执行”。
这一步比后面写多少行代码都重要。 手动流程越乱,自动化死得越快。
二、200 行里,六个设计让“4 分钟”成立下面是他代码里的六个关键设计。每一处都对应一个“如果不这么做,时间就会从 4 分钟涨回 3 小时”的点。
1. 用 getByRole,而不是 CSS class 或 XPath这是整个脚本最值钱的一行习惯。
Playwright 的官方推荐是:优先用基于角色的定位器(getByRole、getByLabel、getByText) 。原因很简单:CSS class 和 DOM 结构会随着样式重构、组件封装、甚至一次“看起来不影响功能”的提交而变;但“用户眼中的按钮是什么角色、叫什么名字”不会轻易变。
数据也很硬:**基于角色的定位器能把测试的脆弱性降低 60% 到 80%**。
代码写出来是这样的:
page.get_by_role("button", name="提交订单").click()
page.get_by_label("邮箱").fill("[email protected]")
而不是:
page.click("button.btn-primary.submit-order") # 明天可能就没了
少写一行 CSS 选择器,未来就少修两小时脚本。
2. 不写 sleep(),让 Playwright 自己等手动测试里,人会“看一眼页面加载好了没”。脚本里如果用 time.sleep(3),就是在用固定时间赌页面速度——赌输了 flaky,赌赢了浪费。
Playwright 的执行动作之前会自动检查元素的可见性、可操作性和稳定性,等待逻辑内建在 API 里,不需要你手动写。
他的脚本里几乎没有 sleep。光这一项,就把大量“跑一次 3 小时里有 40 分钟在等”的隐性浪费挤掉了。
3. POM 只留一个最薄的版本他没有搭八层架构。页面对象模型(POM)只做了最薄的一层:把“账单页”的定位器和操作封成一个类,测试逻辑里只调方法,不碰选择器。
POM 的收益是有数据支撑的:**能把测试维护时间减少 40% 到 60%**。哪怕只有两三个页面,这层封装也让后面改定位器时只需要动一个地方,而不是满脚本搜替换。
4. 并行不是“炫技”,是“把等待重叠起来”Playwright 原生支持并发执行,不需要像 Selenium 那样搭 Grid。在 4 核机器上,并行执行 10 个任务的耗时比串行快约 7 倍。
他的 200 行里没有复杂的并发调度,只是在 pytest 层面开了并行。大部分 UI 测试的时间花在等浏览器和等网络上,不是花在 CPU 上,所以并行带来的 wall-clock 压缩非常直接。
5. 断言分三层,不做“status == 200”式的假通过UI 自动化最常见的“假通过”是:页面显示了“提交成功”,脚本就判通过——但后台订单根本没生成。
他的断言分三层:
- UI 层:关键元素可见、文案正确
- 网络层:捕获关键请求,校验响应状态码和核心字段
- 业务层:通过接口或数据库确认最终状态
200 行里大概有 30 行花在这三层校验上。 这 30 行决定了脚本是在“替你确认质量”,还是在“替你走个过场”。
6. 用自愈兜住“定位器突然失效”的那一下UI 自动化的头号杀手不是逻辑写错,是前端改了一个 class 名,几十条用例集体红。
他在脚本里挂了一个轻量的自愈层。当原定位器找不到元素时,AI 分析页面结构,按“角色 → 标签 → 文本 → data-testid”的优先级重新找目标元素。
自愈不是万能的——它可能修到一个语义相近但不对的元素上,把真 Bug 遮掉。所以他的做法是:自愈操作记录完整日志,定期人工抽查“自愈后是否真的正确”。但至少在“前端又改了一版样式”的日常波动里,脚本不会一觉醒来全红。
三、4 分钟怎么来的?把数据摆在一起单看“3 小时 → 4 分钟”像标题党。拆开看,每一段压缩都有依据。
Playwright 的单步操作耗时约 290 毫秒,Selenium 约 536 毫秒;同样 250 条用例,Playwright 跑 3 分 48 秒,Selenium 要 6 分 52 秒。Playwright 通过复用浏览器上下文,冷启动可以压到 1 秒以内,而 Selenium 每次都要完整拉起浏览器进程,通常 2 到 5 秒。
再叠上并行:4 核上并行 10 个任务比串行快约 7 倍。再叠上 POM 减少的维护时间、语义定位减少的脚本修复时间、自愈兜住的偶发失败排查时间——
3 小时里,真正“必须串行、必须人工判断”的部分本来就不多。剩下的都是可以被自动化吃掉的动作和等待。
四、避坑指南:4 分钟不是抄 200 行就能复现的坑一:把“手动流程”原封不动翻译成代码。 手动流程里混着大量“人顺手做的判断”和冗余步骤。不先做减法,200 行会膨胀成 2000 行,而且更脆。
坑二:定位器随手写 CSS class。 你今天写的 .btn-primary,明天前端重构就没了。定位器优先级:getByRole → getByLabel → getByText → getByTestId → 最后才是 CSS。
坑三:只用 UI 状态做断言。 页面说“成功”不等于业务成功。必须捕网络请求、查业务状态,否则脚本只是在帮你确认“按钮点得动”。
坑四:把自愈当万能药。 自愈可以把一个真回归“修”成一个通过的测试。每一次自愈都必须留日志、可审计,人工定期复核。
坑五:一上来就追求“全自动”。 先从一条最稳定、最重复的流程开始跑通闭环。跑通一条 4 分钟的,比写十条永远在修的两小时脚本有价值得多。
五、认知升级:200 行省下的不是 15 小时,是“做判断的时间”那个朋友后来跟我说了一句话,我记到现在:
“以前我一天里大部分时间在‘操作’,只有一小部分在‘思考’。现在反过来了。”
200 行代码替掉的是登录、填表、点提交、等加载、查表格。留下来的,是“这次改动到底该重点测哪里”“这个失败是真 Bug 还是脚本问题”“这个版本能不能发”。
工具切换者 在五个系统之间复制粘贴、人肉搬运结论。工作流设计者 定义流程、写清规则、让脚本去执行。
你不需要写 2000 行。你需要写 200 行,每一行都知道自己在替掉哪一个“本来不该由人来做”的动作。
本文部分内容参考了霍格沃兹测试开发学社整理的相关技术资料,主要涉及软件测试、自动化测试、测试开发及 AI 测试等内容,侧重测试实践、工具应用与工程经验整理。














