上个月帮一个团队做测试用例评审翻到一份下单模块的用例集两百多条全是手机号必填密码长度6到20位验证码错误提示这类字段级校验。我问了一句用户领完优惠券、地址填错又重新改、支付超时退回再付这一整条链路谁覆盖了会议室安静了几秒。这就是场景法要解决的问题——它不盯单个输入框而是盯用户完成一件事的整条路径。场景法Scenario Testing本质上是一种以业务流程为线索设计测试用例的方法核心是把需求拆成基本流、备选流和异常流再用这些流组合出用户真实可能走到的路径。它能补上功能点测试覆盖不到的集成缺陷、状态残留缺陷和流程跳转缺陷特别适合订单、支付、审批、注册登录这类有明确步骤的业务系统。这篇内容我会把场景法的概念边界、路径推导、用例模板、常见坑和团队落地方式一次讲清不管你是刚入行的测试新手还是带团队的质量负责人都能直接拿去用。1. 场景法到底在解决什么问题1.1 需求文档里的功能点和用户脑子里的任务不是一回事需求文档通常按模块写登录模块、购物车模块、订单模块、支付模块。每个模块下面列一堆功能点和校验规则。测试人员如果照着这个结构写用例天然就会写出模块内正确、模块间断裂的用例集。用户不会按模块办事用户脑子里想的是我要把这双鞋买回家这个任务横跨了登录、搜索、加购、结算、支付、查看订单六个模块。场景法做的第一件事就是把视角从模块功能切换到用户任务。这个切换带来的直接收益是缺陷发现类型的改变。功能点测试擅长抓输入非法值时提示是否正确这类局部问题抓不到用户从商品详情页点立即购买跳过了购物车优惠券计算逻辑没走到这类跨模块问题。后者恰恰是线上事故的高发区因为开发在写每个模块时都自测过唯独没人测过模块之间的缝隙。场景法就是专门去踩这些缝隙的。我自己的经验是一个中等复杂度的业务系统功能点用例能覆盖大约六到七成的缺陷剩下三到四成基本都藏在流程跳转、状态回退、重复提交、并发操作这些场景里。这不是说功能点用例不重要而是两类用例的靶心不一样谁也替代不了谁。1.2 场景法与等价类、边界值、判定表的分工很多新手会问既然有了等价类和边界值为什么还要场景法这个问题问得好答案是它们解决的是不同维度的问题不是替代关系。方法关注对象擅长发现典型输出等价类划分单个输入域的取值集合输入校验遗漏有效/无效等价类表边界值分析输入域的临界点边界处理错误边界值用例判定表多个条件的组合逻辑条件组合遗漏条件动作表场景法业务流程的路径流程跳转、状态残留、集成缺陷场景路径 端到端用例实际项目里这四种方法是配合使用的。我的习惯做法是先用场景法把主流程和关键分支的骨架搭出来再在每个场景节点上挂等价类和边界值用例做填充。这样得到的用例集既有纵向的流程覆盖又有横向的输入覆盖结构上不会散。举个具体例子。一个提交订单的节点场景法负责回答从哪来、到哪去、中间经过哪些状态等价类和边界值负责回答金额填0、填负数、填超过库存的数量分别怎么处理。前者决定用例的骨架后者决定用例的血肉。只做前者会漏输入校验只做后者会漏流程缺陷。1.3 什么项目适合场景法什么时候别硬套场景法不是万能药它有明确的适用边界。判断标准很简单这个系统有没有用户需要按顺序完成多个步骤才能达成目标的特征。有就适合没有硬套就是浪费工时。适合的典型场景包括电商下单与支付、金融开户与转账、审批流、注册登录与实名认证、机票酒店预订、退款售后、多步骤表单提交、有状态机的订单流转。这些业务的共同点是存在明确的步骤顺序和状态迁移走错一步或者中途退出都会产生不同的结果。不太适合硬套的情况也有纯计算类工具比如单位换算器、静态展示页面、单一接口的参数校验。这些内容用等价类和边界值就够了硬画场景图反而增加维护成本。我曾经见过一个团队给一个只有三个输入框的计算器画了场景图评审时大家面面相觑这就是方法用错了地方。还有一个容易被忽略的点场景法对需求文档的完整度有要求。如果需求里对异常分支的描述含糊比如只写了支付失败要有提示没写失败后订单状态怎么变、库存要不要回滚、优惠券要不要退回那场景法推出来的路径就是残缺的。这种情况下正确做法是先推动需求澄清而不是自己拍脑袋补全然后写一堆假设用例。2. 把基本流、备选流、异常流讲透2.1 基本流的定义标准一条无干扰的主干路径基本流Basic Flow是整个场景的主干定义是用户从触发事件开始一路顺利走到目标达成中间不发生任何分支、回退、错误的那条路径。它必须足够干净不能夹带任何条件判断。以注册登录为例基本流就是打开注册页 → 输入合法的手机号和验证码 → 设置符合规则的密码 → 提交 → 注册成功 → 自动登录 → 进入首页。这条路径上每一步都成功没有任何如果。定义基本流时最容易犯的错是把备选流混进来。比如有人会把用户选择手机号注册写进基本流这就错了因为选择手机号注册本身就是一个分支判断意味着还存在邮箱注册这个备选。基本流里不应该出现选择这个词一旦出现说明你已经在描述分支了。我判断基本流是否干净有个土办法把这条路径念给一个不懂测试的人听如果他听完觉得这不是废话吗正常操作不都这样那基本流就定义对了。基本流就应该平淡无奇它是所有异常的参照系。2.2 备选流和异常流区分它们比记住定义更重要备选流Alternate Flow是合法的分支路径用户走了这条路也能达成目标只是路径不同。异常流Exception Flow是非法的或者出错的路径用户走这条路目标达不成系统需要给出正确处理。区分这两者的关键看业务上是否允许。同样一个操作业务允许就是备选业务不允许就是异常。比如支付环节用户选择货到付款而不是在线支付这是备选流因为业务支持用户在线支付时余额不足导致支付失败这是异常流因为目标没达成。类型判定标准举例用例设计侧重基本流无分支、全成功手机号注册并自动登录验证主链路通畅备选流合法分支、目标可达改用邮箱注册、改用货到付款验证分支逻辑正确异常流非法或出错、目标不可达验证码错误、支付余额不足验证错误处理与状态回滚这个区分之所以重要是因为它直接决定用例的预期结果怎么写。备选流的预期结果是目标达成数据正确异常流的预期结果是目标未达成系统给出提示且相关数据状态正确回滚。很多新手写异常流用例时只写提示支付失败漏掉了订单状态应保持待支付、库存应释放、优惠券应退回这些关键断言结果缺陷就这么溜过去了。2.3 场景路径的组合策略与收敛原则场景不是基本流加所有备选流的全排列那样会爆炸。业界常用的组合策略有三种基本流单独成一条场景基本流加一个备选流成一条场景基本流加一个异常流成一条场景。这种主干加单分支的策略能覆盖绝大多数真实情况同时把路径数量控制在可维护范围内。我通常用一个三层收敛原则来控制路径规模。第一层所有备选流至少被覆盖一次保证合法分支都走到。第二层所有会导致状态变更的异常流必须覆盖比如支付失败、库存扣减失败、超时取消这些会改变数据状态的异常是高危区。第三层组合型异常按风险挑比如支付失败的同时优惠券已核销这种双异常叠加只挑业务上最可能发生的两三个组合来测不追求穷尽。提示路径数量超过三十条时先停下来做一次风险排序把路径按发生概率 × 业务影响打个分低分路径合并或者标记为低优先级不要为了覆盖率数字硬堆用例。这套收敛逻辑背后的道理是测试资源永远有限场景法的价值在于用有限路径逼近真实使用分布而不是数学意义上的全覆盖。把高频路径测透比把低频路径测全更有意义。3. 从需求到可执行用例场景法完整落地流程3.1 第一步事件流梳理与场景节点识别拿到需求后别急着画图先把事件流用文字列出来。事件流就是用户做了什么 → 系统响应什么的序列。我习惯用一张两列表格来梳理左边写用户动作右边写系统响应一行一个步骤。梳理时有个关键动作叫节点识别哪些步骤是普通步骤哪些步骤是决策点。决策点的特征是系统在这里会根据条件走不同分支比如库存是否充足优惠券是否可用支付是否成功。把所有决策点圈出来它们就是后续画场景图的岔路口。这一步的产出物是一份事件流清单和一份决策点清单。清单要写到什么颗粒度我的标准是一个不了解这个业务的人拿着清单能复述出完整流程。如果复述不出来说明颗粒度太粗回去补。3.2 第二步画场景图并推导路径集合场景图用活动图或者流程图都行重要的是节点和边的语义清晰。节点是状态或者动作边是流转条件。画的时候从基本流开始把主干画直然后把每个决策点的分支从主干上引出去异常分支用不同的线型或者颜色区分。画完图之后做路径推导。推导方法是深度优先遍历从起点出发遇到决策点就分叉一直走到终点每走到一个终点就记录一条完整路径。推导过程中要专门盯住三类路径只走主干的、走一次分支的、走异常后回退的。下面是一段下单支付的场景路径表述用 Gherkin 语法写出来目的是让你看到路径推导完直接就能转成可执行用例Feature: 订单提交与支付 Scenario: 基本流 - 在线支付成功 Given 用户已登录且购物车中有1件库存充足的商品 When 用户进入结算页并选择默认收货地址 And 用户选择在线支付并提交订单 And 支付网关返回成功 Then 订单状态变更为待发货 And 商品库存扣减1件 Scenario: 备选流 - 使用优惠券下单 Given 用户账户中有一张满100减20且未过期的优惠券 When 用户在结算页勾选该优惠券并提交订单 Then 订单实付金额为商品原价减20元 And 该优惠券状态变更为已使用 Scenario: 异常流 - 支付超时后取消 Given 用户已提交订单但未完成支付 When 超过30分钟支付时限 Then 订单状态变更为已取消 And 商品库存回滚1件 And 已核销的优惠券退回用户账户这种写法的好处是路径、前置条件、动作、断言四要素齐全评审时业务方也能看懂而且可以直接被 Cucumber 这类工具解析成自动化脚本。我个人强烈建议场景用例至少用这种结构写一遍比纯文字描述严谨得多。3.3 第三步用例模板设计与参数填充路径推导完只是骨架还要往每条路径上挂具体数据。我用的用例模板包含这些字段用例编号、场景名称、优先级、前置条件、测试数据、操作步骤、预期结果、关联需求。其中测试数据字段最容易被敷衍。我的要求是数据必须具体到可以直接执行不能写输入一个合法金额要写输入99.99。因为一旦写成模糊描述执行阶段不同的人会填不同的值覆盖效果完全不可控。同理前置条件也要具体到状态不能写用户已登录要写用户A已登录账户余额100元购物车有2件商品。参数填充有个技巧叫一景一数据同一个场景节点上的不同数据值拆成不同的场景实例。比如支付环节测余额充足和余额不足是两条独立场景不是一条场景里的两个数据。这样拆的好处是用例之间互相独立执行失败时定位快。3.4 完整示例一段下单流程的场景法拆解拿一个简化的电商下单流程做完整演示。需求是这样的用户从商品详情页点击立即购买进入结算页选择地址、选择优惠券、选择支付方式提交订单跳转支付支付成功后订单进入待发货。第一步梳理事件流和决策点得到决策点清单库存是否充足、地址是否有效、优惠券是否可用、支付方式是在线还是货到付款、支付是否成功、是否超时。第二步推导路径收敛后得到八条核心场景编号场景描述类型优先级SC-01库存充足、默认地址、无券、在线支付成功基本流P0SC-02库存充足、新增地址、用券、在线支付成功备选流P1SC-03库存充足、货到付款备选流P1SC-04库存不足提交时拦截异常流P0SC-05地址已失效提交时提示重选异常流P1SC-06在线支付失败订单保持待支付异常流P0SC-07支付超时订单取消、库存回滚、券退回异常流P0SC-08提交订单时重复点击只生成一笔订单异常流P0第三步为每条场景填充数据和断言。以 SC-07 为例前置条件写用户已提交订单订单号XXX状态待支付库存已扣减优惠券已锁定操作步骤写等待超过30分钟或手动触发超时任务预期结果写订单状态变为已取消库存加回1件优惠券状态由锁定变为可用用户收到取消通知。这三条断言缺一条都算用例不完整。SC-08 这条特别值得说。重复提交是真实环境的高频问题用户手抖点两下、网络慢导致页面没反应又点一次都会触发。这条场景的断言核心是幂等无论点几次只产生一笔订单、一次库存扣减。这类缺陷功能点用例几乎抓不到只有场景法会专门去想用户在这个节点上可能做出什么非预期操作。4. 场景用例的设计细节与避坑经验4.1 触发条件、前置状态、数据准备的写法场景用例和普通用例最大的差别在于前置状态复杂。普通用例前置条件可能就一句已登录场景用例的前置往往涉及多个模块的数据状态。写不好执行阶段就得花大量时间造数据用例根本跑不起来。我的做法是把前置条件分成三类写环境类哪个环境、哪个账号、数据类账户余额、库存数量、券的状态、状态类订单当前处于哪个状态。三类分开列造数据的人一眼就知道要准备什么。数据类前置尽量用接口或者脚本预置别依赖手工点手工造的数据不可复现出了问题没法回溯。还有一个细节前置条件里涉及时间的地方要写清楚时区或者相对时间。比如优惠券24小时内过期要写成优惠券有效期截止到执行时刻加24小时否则换个人换个时间执行结果就不一样。4.2 断言与预期结果怎么写才不留坑预期结果是场景用例的灵魂也是新手最容易写薄的地方。我的经验是一个场景的预期结果至少要覆盖四个层面界面层提示文案、页面跳转、数据层订单、库存、账户余额、状态层订单状态、券状态、通知层短信、站内信、消息推送。界面层最好写数据层和状态层最容易漏。举个真实踩过的坑一个退款场景界面提示退款成功开发自测也过了但实际账户余额没增加因为退款回调里漏了一个字段映射。这个缺陷靠界面断言永远发现不了只有把账户余额增加X元写成明确断言才能抓到。从那以后我写涉及资金或者库存的场景数据层断言是强制项。断言还要注意精确和模糊的取舍。金额、数量、状态这类离散值必须精确断言时间戳、日志这类可以用范围断言。别为了省事全写成操作成功那样的断言等于没写。4.3 场景法用例的优先级排序场景用例数量通常不少全量执行成本高必须有优先级。我用的排序模型是两个维度业务影响高/中/低和发生概率高/中/低。两个都高的定 P0必须每次回归业务影响高但概率低的定 P1版本回归时跑两个都低的定 P2大版本才跑。按这个模型基本流永远是 P0因为它发生概率最高。会导致资金损失、数据错乱的异常流也是 P0比如支付、退款、库存扣减。纯提示类的异常流一般是 P1。这样排下来 P0 用例通常只占总量的两到三成但覆盖了八成以上的风险回归效率能明显提上来。注意优先级不是一次定终身。线上出过一次事故的路径哪怕概率再低也要临时提到 P0事故路径的回归价值远高于理论概率。5. 常见问题与排查技巧实录5.1 场景爆炸路径数量失控怎么收敛决策点一多路径数量是指数级增长的。六个决策点、每个两个分支理论路径就有六十四条。真按这个写用例写到手软也写不完维护更是灾难。收敛的实操办法有这么几个。第一把决策点按是否影响最终状态分类不影响状态的纯展示型分支直接砍掉。第二将互斥的分支合并比如手机号注册和邮箱注册是互斥的一个场景里只会走一条不用组合。第三对低频异常做等价合并几种不同的输入校验失败可以合并成一条输入非法时统一提示的场景。第四用成对组合代替全排列只测两两组合不测三三组合。我实际项目里的经验值是一个有十个左右决策点的业务流程收敛后控制在二十到三十条场景是比较健康的。超过四十条基本可以判定有冗余回头重新审视一下哪些路径是理论存在但业务上永远不会发生的。5.2 场景遗漏怎么判断覆盖够了覆盖度判断不能只看用例条数。我用的检查清单有四问所有备选流是否都至少有一条场景覆盖所有会改变数据状态的异常流是否都覆盖所有跨模块的跳转点是否都覆盖所有不可逆操作支付、提交、删除是否都有重复操作场景这四问过一遍遗漏基本能兜住。另外还有个笨办法但很有效找业务方或者产品经理让他们口述三个真实用户的操作故事你拿场景库去对看能不能对上。对不上的就是漏掉的场景。业务方讲的故事往往带很多用户会先怎样再怎样的细节这些细节是需求文档里不会写的恰恰是场景法要抓的东西。5.3 执行阶段的高频问题速查表场景用例执行阶段的问题和普通用例不太一样很多是环境或者数据导致的假失败。整理了一张速查表遇到问题先按这个对一遍。现象可能原因排查动作前置数据造不出来依赖的上游状态未就绪检查数据脚本的执行顺序确认上游模块已初始化断言失败但界面正常数据层断言取数时机太早加等待或改用最终态查询避开异步延迟同一用例两次结果不同用例之间有状态污染检查用例是否共享账号或订单改成独立数据异常流跑不出异常环境配置把校验关了确认环境开关和线上一致别在mock环境验异常超时类场景无法触发定时任务周期太长用配置缩短周期或提供手动触发入口幂等场景测不出重复前端做了防重但后端没测绕过前端直接调接口重复提交验证后端幂等这张表里最后一条是我特别想强调的。很多团队测重复提交只测前端按钮置灰觉得够了。前端防重只能挡住正常用户挡不住网络重试、脚本调用、多端并发。真正的幂等必须在后端验证方法就是绕过页面直接对接口发两次相同请求看数据库里是不是只有一条记录。6. 团队落地让场景法真正跑起来6.1 评审机制与场景库维护场景法在团队里推不动通常不是因为大家不会而是因为写完没人用、用完不维护。要让它活下来得有两个机制评审机制和场景库。评审机制我建议做成轻量的场景走查不用正式评审会那么重。需求评审完测试同学花半小时把场景图和路径清单拉出来拉上产品和开发过一遍重点确认三件事基本流对不对、异常流的预期状态对不对、有没有业务上存在但文档没写的分支。这个动作成本很低但能把大量需求歧义挡在编码之前。场景库维护的核心是场景和需求绑定。每个场景标注它覆盖的需求编号需求变更时能反查出哪些场景要改。场景库不要按项目存按业务域存比如下单域支付域账户域这样跨版本能复用。每出一个线上缺陷回头往场景库里补一条对应场景这是场景库增值最快的方式比坐在那凭空想场景有效得多。6.2 和自动化、接口测试的衔接场景用例天生适合自动化因为它步骤清晰、断言明确。但我不建议一上来就把所有场景都自动化。正确的顺序是先手工把场景跑通、断言校准再挑 P0 且稳定的场景做自动化。断言没校准就自动化等于把错误的预期固化下来后面维护成本更高。和接口测试的衔接点在于场景里的关键节点尽量用接口做数据准备和结果校验中间必要的界面操作才走UI。这种混合模式比纯UI自动化稳定得多也比纯接口测试更贴近真实链路。比如下单场景前置的登录和加购用接口造中间的结算提交走界面最后的订单状态和库存校验再回接口查整条链路既真实又快。最后分享一个我在实际项目里养成的习惯每写一条场景用例都问自己一句如果这条用例上线后还是出了缺陷最可能是哪个断言没写。这个自问能逼着我把断言写厚。踩过几次坑之后我发现绝大多数漏测不是因为场景没想到而是因为想到了但断言写薄了界面提示对了就以为过了数据其实早就错了。场景法真正的价值不在画图那一步而在你敢不敢把每一条路径的最终状态都断言死。
阅读完成 · 觉得有帮助?