为什么我把结算链路从接口测试切到了 UI?一个电商项目的自动化分层复盘

58 阅读8分钟

个人实战复盘 · OpenCart 电商项目 · Requests + Playwright

前言

做 OpenCart 电商项目的时候,我被一个问题困住很久:这个功能,到底写接口自动化,还是 UI 自动化?

最开始我的想法很简单:接口跑得快、不容易崩,能写接口就全部写接口。等到写到结算、完整下单这一整条长链路,才发现这条路走不通。硬用接口模拟用户下单,前置依赖代码一大堆,而且页面上的弹窗提示、表单联动,接口根本看不到。

于是我把这类长流程用例切给了 UI。

但新问题又来了:如果什么都堆 UI 脚本,页面稍微改一点,脚本就挂,维护起来特别折磨。

从头到尾踩完这一轮坑,我才明白:接口和 UI 自动化不是二选一,而是分层配合。

这篇就顺着我拿到这个项目之后的真实操作顺序复盘,讲讲我是怎么一步步选定方案、落地冒烟和回归的。

补充一个背景:我之前做过众测。那段经历让我发现一个问题——众测能发现“现象”,但定位不了“根因”。比如我提交过一个“按钮点了没反应”的问题,只能附上截图和描述,但我不知道是前端事件没绑定,还是后端接口报错,因为我拿不到日志、调不了接口。

所以我开始自学接口和 UI 自动化:我想从“发现现象”走到“定位根因”。OpenCart 这个项目,就是我从广度往深度走的第一步。

一、接口和 UI 自动化的本质区别

在动手之前,我先梳理了一下两者的定位,这也是后续做技术选型的基础:

维度接口测试UI 测试
测试对象后端业务逻辑、数据准确性用户页面交互、端到端流程
执行速度快(毫秒/秒级)慢(秒级,需等待页面渲染)
稳定性高,不受页面 DOM 变动影响较低,页面改版易导致脚本失效
适用场景逻辑校验、边界值、权限验证核心主链路、视觉交互、表单联动

一句话总结:接口测“数据逻辑对不对”,UI 测“用户操作能不能用”。

二、拿到项目,我是一步步落地自动化的

拿到 OpenCart 项目,我先手工跑完核心流程、梳理用例、划分优先级,没有上来就写代码。等核心流程稳定后,才开始筛选适合自动化的场景。

初步想法:全部用接口实现——快、稳定,不用管页面样式。

遇到阻碍:写到结算环节卡住了。OpenCart 的 checkout 依赖 $this->session->data 保存会话,页面表单自带隐藏 token,路由是老式 index.php?route=checkout/xxx。想用 Requests 模拟完整下单,要手动维护 cookie jar、每一步先访问页面抓 token,链路长、步骤多;购物车接口 add 要传 product_id、quantity、option,中间会话一失效整条链路就断。更关键的是,地址格式提示、支付插件联动这类前端交互,接口完全验证不到。

权衡决定:结算类、完整下单类这两类 P0 长流程用例,放弃接口实现,改用 Playwright UI 自动化。

但也不能走另一个极端:商品字段校验、购物车边界参数、token 鉴权这类纯后端逻辑,写成 UI 脚本执行慢、页面一改就报错,维护成本完全不划算。

最终分层方案:

  • ✅ 接口 suite(7 条):其中 2 条结算相关设计上划给 UI,实际执行 5 条,负责纯后端逻辑、边界、权限校验。
  • ✅ UI suite(19 条):只保留用户完整下单主流程。

执行环境:本地 Docker 部署 OpenCart。实测耗时:接口实际执行 5 条约 812 秒;冒烟子集 2 条约 1.52.5 秒;UI 19 条串行约 2 分 10 秒 ~ 2 分 40 秒。

脚本开发:接口用 Requests 封装公共请求、日志、断言,写完 5 条,挑出商品查询、加购 2 条做冒烟;UI 基于 Playwright + POM 分层封装登录、商品、购物车、结算页面。因为 OpenCart 支持 OCMod/vQmod 插件,第三方插件改 DOM 后选择器直接失效,所以我刻意控制 UI 用例数量,只守核心主链路。

冒烟和回归的执行规则:

  • 新版本部署 / 提测:先跑接口冒烟。冒烟失败说明后端核心链路出问题,直接打回开发,不再跑后面的自动化。冒烟通过后,我会手工快速走一遍极简下单——因为 UI 自动化放在夜间定时任务,提测阶段环境不稳定,UI 脚本暂时也没覆盖全部支付插件,手工可以快速兜底。
  • 日常代码提交:只跑接口全量回归。
  • 夜间定时任务:跑 UI 核心回归。
  • Bug 修复后:先验证当前 bug,再跑关联用例,不盲目全量。

额外踩坑:电商自动化容易产生脏数据。我的处理是——每条下单用例执行完调用后台接口清理订单;库存场景测试结束后通过数据库回滚恢复库存。 CI 配置:GitHub Actions 调度脚本,UI 用例失败自动截图。

三、什么场景用接口,什么场景用 UI

✅ 优先接口

  1. 商品详情接口返回字段是否完整正确 —— 纯后端数据逻辑。
  2. 购物车传数量 0 / 负数 —— 前端会拦截,只有直调接口才能验后端防护。我实测用 Apifox 直调,传 0 会被拦截,但传 -5 居然加购成功了。
  3. token 鉴权、越权访问 —— 带不同 token 请求,不用打开页面。

bug_06_quantity_negative.png

顺带说一下这条测出来的 bug:购物车数量传负数也能加购(传 0 会被拦截),我定为 P2——不影响主流程,但数据异常。

定级参照的口径是:P0 致命、P1 严重、P2 一般、P3 轻微界面问题、P4 优化建议。虽然是个人项目,没有产品、开发一起评审,但定级这件事本身值得做——找 bug 靠细心,定级靠判断。

✅ 优先 UI

  1. 登录→浏览→加购→填地址→选支付→提交订单的完整主链路。
  2. 页面跳转、弹窗、表单联动这类前端渲染效果。

四、整套分层执行流程

场景策略
新功能提测手工冒烟 + 接口验证后端逻辑
日常迭代回归接口为主,UI 为辅
上线前接口全量 + UI 核心 19 条
bug 修复验证先验证当前问题,再跑关联模块回归

五、踩坑反思(完整思考过程)

整个项目的试错路径,就是我认知变化的过程:

  1. 一开始想法:接口快、稳定,想全部用接口搞定所有场景。
  2. 遇到阻碍:OpenCart 结算长链路,会话、隐藏 token 处理繁琐,接口模拟代价太大,前端交互校验覆盖不到 → 把这两类长流程用例切换为 UI 自动化。
  3. 又踩坑:如果把简单逻辑也全部写成 UI 脚本,执行慢,页面稍微改动脚本就批量失败,维护压力很大。OCMod 插件改动页面 DOM,选择器直接失效,进一步放大维护成本。
  4. 最终平衡:接口负责底层业务逻辑,UI 负责真实用户主流程,各司其职。

回头看,这个分层方案不是一开始就设计好的,是动手做到卡住、踩了坑之后,一步步调整出来的。  如果一开始就想清楚“什么该接口、什么该 UI”,能少走很多弯路。

结尾

接口和 UI 自动化从来不是二选一,是分层配合。

接口测逻辑,速度快、稳定性强,适合高频日常回归;UI 测真实用户流程,验证页面交互,用来保障核心主链路。

冒烟抓核心,回归看全量。

最后说一点感悟。做完这个项目,我最大的收获不是学会了 pytest 或 Playwright,而是理解了测试的本质是“分层配合”:

  • 手工测试负责探索和体验——新功能、复杂交互,脚本暂时搞不定
  • 接口测试负责底层逻辑——快、稳定、能测边界
  • UI 测试负责端到端流程——验证用户真实操作能不能走通

它们目的相同(验证质量),手段不同;被测对象决定手段,而成本决定配比。

这也让我重新理解了之前的众测经历:众测擅长在大量真机真环境里快速发现“现象”,而自动化和专项测试负责往下追“根因”、守主链路。前者偏广度,后者偏深度,两者是互补的,不是高低之分。

我从众测出发,往深度走了一步。这个项目就是证明。

✅ 自动化选型简易 Checklist(可直接收藏)

遇到新功能拿不准选接口还是 UI,问自己 3 个问题:

  1. 功能正确性,只看返回数据能不能判断? → 是,优先接口
  2. 是否存在用户必须肉眼确认的交互(弹窗、表单联动、页面跳转)? → 是,考虑 UI
  3. 脱离前端页面构造测试数据、模拟链路的成本,会不会超过收益? → 成本过高,交给 UI

我的默认配比:新项目优先 80% 接口 + 20% UI。UI 只保 P0 主链路。能配套接口用例的尽量配套,成本过高的(比如结算链路)就交给 UI 链路顺带验证,并在用例里标清楚哪些后端点没有被单独覆盖。