返回 Web 功能测试
Main Track / Tutorial 07

业务状态流转测试实战教程

把订单看成“当前状态 + 触发操作 + 流转规则”,验证支付、取消和退款在正常、重复、乱序与并发下是否仍然正确。

9 个章节订单支付退款状态流转 + 并发 + 补偿
01

为什么复杂业务要明确状态流转

不只测试页面按钮

当前状态决定接下来允许做什么

订单处于“待支付”时可以支付或取消;进入“已支付”后可以履约或退款,却不应回到普通待支付。把当前状态、触发操作和目标状态整理成规则,专业上称为“状态迁移测试”,部分资料也称“状态机测试”。

简化订单状态图
待支付

支付 → 已支付
取消/超时 → 已关闭

已支付

申请退款 → 退款中

退款中

渠道成功 → 已退款
渠道失败 → 可重试

当前状态

某一时刻可以稳定观察的业务阶段。

触发操作

用户、定时任务或外部回调发起的动作。

流转规则

允许条件、目标状态、数据副作用和失败处理。

02

从需求建立状态模型

先穷举再执行

建模步骤

  1. 找出订单、支付单、退款单三个状态主体。
  2. 列出每个主体所有可观察状态。
  3. 标出用户操作、超时任务和渠道回调事件。
  4. 为每次迁移写前置、目标状态和副作用。
  5. 补上失败、重复、乱序和人工处理路径。

订单合法迁移表

当前状态事件目标状态关键副作用
待支付支付成功已支付支付记录成功,库存保持已扣减
待支付用户取消已取消释放库存,优惠券可恢复
待支付超时关闭已关闭拒绝后续普通支付
已支付申请退款退款中创建一笔退款单
退款中渠道退款成功已退款资金、订单和退款单一致
状态名称要能由接口或数据查询证实。“处理中”若没有明确进入和退出条件,就还不是可测试的状态定义。
03

覆盖每一条合法状态迁移

节点与边都要测
一条迁移的完整断言
前置状态待支付
触发事件支付成功
目标状态已支付
业务副作用支付记录与通知

合法迁移用例

  • 当待支付订单完成支付时,订单进入已支付且支付记录成功。
  • 当待支付订单超过有效期时,订单关闭并释放库存。
  • 当已支付订单满足退款条件时,创建退款单并进入退款中。
  • 当退款渠道返回成功时,订单进入已退款且金额一致。

每条迁移至少验证

  • 事件前状态与权限满足前提。
  • 接口返回 HTTP 200 后,业务码说明本次业务是否受理。
  • 主体进入唯一目标状态。
  • 库存、金额、优惠券和消息副作用正确。
  • 页面能够展示最新状态且操作入口同步变化。
04

主动验证非法迁移

不能走的路同样重要

非法迁移与预期防线

非法迁移触发方式预期
已取消 → 已支付迟到的支付成功回调拒绝直接覆盖;进入异常处理或补偿
已退款 → 退款中重复点击退款返回原退款结果,不新建退款单
待支付 → 已退款跳过支付直接改状态拒绝并记录审计
已支付 → 待支付人工错误回退禁止普通接口逆向迁移

执行方式

  1. 通过测试接口或可控工具准备指定状态。
  2. 发起在当前状态不允许的事件。
  3. 确认接口拒绝且返回明确业务原因。
  4. 核对订单及关联数据完全不变。
  5. 检查审计日志和告警是否满足设计。
05

制造并发事件和竞争条件

顺序不同,结果仍要守约束
支付成功与超时关单竞争
事件 A

支付渠道回调成功

事件 B

超时任务尝试关单

唯一终态

按锁、版本或规则只接受一条迁移

关键并发用例

  • 当支付成功和超时关闭几乎同时发生时,订单只进入一个合法终态。
  • 当用户 A 与客服同时发起退款时,只创建一笔有效退款。
  • 当两个设备同时提交最后一件库存时,只允许一笔订单占用成功。
  • 当支付回调与用户查询并发时,查询不得展示不存在的中间组合。
并发测试要记录每个请求的发送时间、幂等键、request_id 和最终数据;只看两次页面点击无法证明竞争条件。
06

验证重复提交与幂等

相同意图只产生一次结果
幂等处理的核心路径
首次请求携带幂等键
保存结果状态与响应
重复请求识别相同意图
返回原结果不重复副作用

幂等检查

场景操作必须成立
重复下单同一幂等键连续提交只有一个订单,库存只扣一次
重复支付按钮双击或网络重试只有一笔有效支付
重复回调渠道发送相同通知状态不二次推进
重复退款相同退款请求重放金额不累计,返回原退款单
07

测试失败回滚与异步补偿

失败后仍能恢复
外部成功后的恢复路径
支付已成功外部事实
订单更新失败局部异常
记录待补偿可追踪
重试或人工恢复一致

故障场景

  • 当订单创建后库存扣减失败时,订单不进入可支付状态或被可靠关闭。
  • 当支付成功但订单更新失败时,补偿任务根据支付事实推进订单。
  • 当退款成功但消息发送失败时,可重试消息且不重复退款。
  • 当补偿连续失败时,系统告警并进入可人工处理状态。
回滚适合尚未对外生效的本地操作;外部支付已经成功时不能假装回滚资金,必须通过补偿和对账恢复一致。
08

核对跨对象状态与数据一致性

一个订单,多份事实

终态一致性断言

订单状态支付单退款单库存与优惠券
待支付未支付不存在按规则锁定
已支付成功且金额一致不存在库存已扣,优惠已使用
已取消/关闭无成功支付不存在库存与优惠已释放
退款中支付成功处理中按业务约定处理
已退款支付成功成功且不超实付按规则恢复

可执行核对

  1. 保存订单号、支付单号和退款单号。
  2. 查询接口返回的当前状态和业务码。
  3. 核对数据库中的主体版本、金额和更新时间。
  4. 检查库存、优惠券、消息和账务副作用。
  5. 在最终一致性时间窗后再次查询。
  6. 超时仍不一致时保存证据并触发告警。
09

完成一套订单状态流转测试

从规则到证据

练习

  1. 画出待支付、已支付、已取消、退款中和已退款。
  2. 为每条合法流转写一条“当……时,……”用例。
  3. 补充四条非法流转并验证数据不变。
  4. 设计支付与关单、退款与重复回调两个竞争场景。
  5. 验证下单、支付和退款的幂等键。
  6. 模拟订单更新失败并检查补偿与告警。

规则完整

  • 状态可观察
  • 操作已穷举
  • 终态明确
  • 副作用明确

异常充分

  • 非法流转拒绝
  • 并发终态唯一
  • 重复请求幂等
  • 乱序可处理

结果可信

  • 多对象一致
  • 补偿可验证
  • 告警可触发
  • 证据可追溯