简介:《测试用例编写指南》是一份面向软件测试人员、测试设计初学者及技术管理人员的规范型文档,针对用例编写凭惯性、颗粒度与详略不一、可读性差等常见问题,梳理从需求分析到用例维护的完整流程。压缩包内共1个docx文件,约494KB,文档含修订记录、适用范围、测试设计依据及用例模板字段说明,篇幅精炼,便于随项目查阅。全文围绕需求分析、业务流程分析、系统设计分析、用例编写与完善五步展开,明确测试需求与用例的字段要素、需求及用例划分原则、测试类型与设计方法,并对等价类划分、边界值分析、状态迁移等方法给出说明,同时补充测试用例维护与风险建议,覆盖正常、异常及边界场景的检查点设计。已有551人学习,适合希望统一团队编写口径、补齐测试设计知识空缺并提升投产质量的读者参考。
1. 用例里最容易忽略的编写注意点,往往源于被跳过的工作
谈用例编写注意点,多数人先想到格式:标题怎么写、步骤分几列、预期填几行。但真正让一份用例在三个月后还有价值的,恰恰不是格式。我见过一个团队,用例评审全票通过,半年后版本回归,没人敢执行那批用例——步骤里混着检查结果,预期里混着操作动作,一条用例挂三个预期分支却只给一组步骤,执行的人得先猜作者当时在想什么。测试用例最先要面对的是三个月后照着它点鼠标的人,以及将来可能把它转成自动化脚本的那套代码。这份指南里每一条看起来刻板的要求,背后都对应着某类具体返工,拆开看才知道它防的是什么。
2. 五步法拆解:需求怎么被切成可执行检查点
五步法看起来像流程装饰,实际是一次逐层补信息的过程:需求分析拿到的信息最粗,业务流程分析补业务常识,系统设计分析补代码改动面,第四步才落到用例,第五步负责收口。每一层的输出都是下一层的输入,任何一层偷懒,最终都会变成用例里那句含糊的“操作成功”。
2.1 需求分析:业务需求说明书为什么不能直接当测试需求
业务需求说明书是按人和业务场景写的,一段话里可能裹着三四个判断分支、两个角色权限和一条隐含的数据约束。它描述的是“业务上要达成什么”,不是“系统在什么条件下必须表现成什么样”。第一步做的事情本质上是翻译:把流程型描述转成判定型描述,把“用户可以登记合同”转成“必填项为空时提交应返回字段级提示”“合同金额等于授信上限时应允许提交”“同一合同编号重复登记应被拒绝”。
这三条就是检查点。检查点的定义很硬:它是一个可以被判定真假的断言单元,不是一个动作,也不是一段说明。指南里那几条划分说明其实都在服务这个定义——一个功能的正常流程对应一个检查点;一个功能里含多个正常场景或多个异常流程,就分别列多个检查点;同一功能需要准备多份不同数据,原则上分别列检查点,只有当多份数据必须同时参与一次操作时才合并成一个组合检查点。
最后一条最容易踩偏。很多人把“准备十份数据跑同一个接口”写成一条检查点,理由是“操作是一样的”。但十份数据里只要有一份结果不对,这条检查点就处于“部分失败”状态,而一条用例只有通过和不通过两个终态,中间态没法记录,缺陷定位就被迫从“哪份数据出问题”重新查一遍。检查点的粒度实际上决定了后面缺陷定位的成本下限。
需求路径的写法也在这一步定型:/项目名称/一级需求/二级需求/.../N级需求。这个形式看着像文档目录,其实是后面所有统计的分母。路径定歪了,覆盖率永远算不准,第 3 章会展开。
2.2 业务流程分析:补的是需求文档不会写的那部分
第二步的输入是业务背景知识和被测系统的实际业务流程,输出是“需求文档没提、但必须验证”的检查点。这一步存在的理由很实在:需求文档写的是正常路径,而线上事故绝大部分发生在非正常路径上。写需求的人默认用户会按设计的方式操作,写用例的人不能有这个假设。
需要梳理的东西有四类:主流程、备选流程、数据流向、关键判断条件,外加“完成该操作的必要条件和非必要条件”。以一个审批类流程为例,主流程是经办提交、复核通过、终审通过;备选流程是复核拒绝、退回修改、超时自动流转;数据流向是单据状态在几张表之间怎么迁移;关键判断条件是金额阈值决定走几级审批。这四样东西在需求文档里往往是散落的,甚至只存在于业务同事的口头描述里。
这一步的产出质量,取决于有没有把流程当成状态机来看。状态机的覆盖思路很简单:每个状态至少到达一次,每条迁移至少触发一次,每个非法迁移至少被拒绝一次。“已审批通过的单据再次提交”这种检查点,需求文档基本不会写,但它对应的缺陷在生产上一点都不罕见。流程类用例之所以在划分原则里按“全流程场景”和“步骤分解”两条线拆,就是因为这两种覆盖目标不一样:全流程验的是串起来能不能跑通,步骤分解验的是每个节点单独的行为边界。
2.3 系统设计分析:影响范围是怎么被算进来的
第三步是整份指南里技术含量最高、也最容易被跳过的一步。输入是概要设计、详细设计、接口设计和数据库设计文档,处理动作是“针对系统为实现业务需求所做的主要改动点及影响范围进行全面分析”,输出是改动功能支持的所有逻辑分支,加上影响范围的回归检查点。
改动点是设计文档明写的,影响范围不是。影响范围要顺着三条线自己推:调用链(谁调用了这个接口、这个接口又调了谁)、数据表(哪些表被读写、哪些字段被改了语义、有没有触发器或存储过程牵连)、消息与定时任务(有没有下游消费者依赖这个数据变更)。举个具体的:某次改动只是给合同表加了一个状态字段,但日终批处理里有一段逻辑按状态汇总,历史数据的状态默认值会让汇总结果整体偏移。这个影响在设计文档里一个字都不会提,只有把数据流向画出来才看得见。
指南把“关联性测试”单列为一种测试类型,定义是“针对不涉及代码改动但与被改动功能有依赖或调用关系的功能进行关联性测试”。这个定义其实就是第三步输出的落地形式。做过几次线上故障复盘的人都会有同感:真正难查的不是改坏的那行代码,是那行代码波及到的、你以为不会受影响的地方。
2.4 第四步的抽样策略:等价类、边界值、因果图分别在控制什么
第四步要把检查点变成用例,而输入空间理论上是无限的。设计方法的作用不是“更全面”,是在有限预算内选一组最有代表性的样本。指南列的方法各有分工,理解分工比背名字有用。
等价类划分管的是“把无限压成有限”。把所有合法输入切成若干类,每类取一个代表,假设同类行为一致。这个假设是方法论的前提,也是它失效的地方——如果实现里对不同长度字符串走了不同分支,等价类就会漏。所以等价类通常要和边界值配合。
边界值管的是“错误高发区”。指南给的口径是刚刚小于、稍小于、等于、刚刚大于、稍大于边界值。这五个点里,等于和两个越界点覆盖 off-by-one 类缺陷,两个内侧点覆盖区间端点处理。用一段代码生成取样点很直观:
def boundary_points(low, high, step=1): """按指南口径生成边界取样点:越界下、边界下、区间内、边界上、越界上""" return [ low - step, # 刚刚小于下界,应被拒绝 low, # 等于下界,通常应通过 (low + high) // 2, # 区间内的正常代表值 high, # 等于上界,通常应通过 high + step, # 刚刚大于上界,应被拒绝 ]这段函数的三个参数分别是被测字段的下界、上界和步长。步长取 1 适用于整数金额、次数这类离散值;浮点字段要注意步长不能小于精度,否则“刚刚小于”和“等于”在存储层会变成同一个值,用例永远跑不出差异。区间内那个中间值不是为了测边界,是给正常路径留一个代表样本,方便失败时区分“边界处理错了”还是“整个功能挂了”。
因果图管的是组合爆炸。指南举的例子是登录页面的验证码、身份证、姓名、密码多条件校验。四个布尔条件就是 16 种组合,六个条件就是 64 种,全排列写用例不现实。因果图加判定表的价值在于把“输入条件的组合、约束关系和输出条件的因果关系”显式画出来,然后按条件的重要性和约束剪枝,保留高价值组合。
错误推测放在这一层是合理的。它是把历史缺陷库转成检查点的过程,指南给的例子是分页场景(查询分页、文件分页)和金额四舍五入。这类检查点的共同特征是:它们不来自需求,来自“上次就在这里翻车过”。
2.5 第五步的触发条件:五种必须更新用例的场景
第五步在指南里写得像维护条款,实际是整个闭环的收口。四种触发场景分别是:评审发现用例有问题、系统新增功能或需求变更、测试过程发现设计时考虑不周存在遗漏、系统出现生产问题经分析为测试泄漏。
第四条最值得单独说。前三类都是“事前或事中发现”,只有第四类是“事后补偿”,也是唯一一次能把线上事故转成组织资产的机会。生产问题的复盘如果只做到“修复代码、发布上线”,那同一个坑过半年换个人还会再踩;做到“补一条检查点、回写进需求路径、反查同类需求有没有同样遗漏”,才算闭环。反查这一步经常被省略,但它的投入产出比最高——一个“金额四舍五入方向不对”的泄漏,往往意味着所有涉及金额计算的模块都要复查一遍。
3. 用例的数据结构:路径树、十二个字段与前置条件的独立性
3.1 需求路径与用例路径:为什么是树而不是标签云
需求路径是层级目录,用例路径在需求路径基础上追加需求名称。这个设计让“用例属于哪个需求”变成结构事实,而不是靠人维护的关联字段。层级结构的价值在三件事上:可统计(任意子树下的用例数、执行通过率)、可定位(一批失败集中在哪个子树,往往指向同一个根因)、可复用(新项目挂同一棵子树,只换数据不改结构)。
用标签做不到这些。标签能回答“这条用例打了‘支付’标签”,但回答不了“支付模块的用例覆盖了需求的百分之多少”,因为标签之间没有父子关系,没有分母。指南里那条说明——同一项目需区分多系统或多需求时,把系统名称或需求名称作为一级需求——本质上是在给树加一层根节点,让分母可切换。
测试需求和测试用例的结构大致是这样:
{ "path": "/模拟项目A/业务管理/合同登记", "name": "合同登记", "description": [ "必填项为空时提交,返回字段级提示", "合同金额等于授信上限时允许提交", "同一合同编号重复登记被拒绝" ], "owner": "设计人A", "systems": ["账务系统", "影像系统"] }description是一个检查点数组,不是一段自然语言。这个细节决定了整个体系能不能算账:数组长度就是这个需求下的检查点数量,下游用例数量、执行轮次、缺陷密度都以它为分母。如果这里写成一段话,后面所有统计都得靠人工重新数一遍。systems是关联系统,跨系统联调和接口测试靠它筛选用例集。
3.2 十二个字段里,哪些给执行器看,哪些给人看
测试用例的字段有:用例路径、测试名称、用例描述、前置条件、操作步骤、预期结果、设计人、优先级、用例类型、用例属性、测试方式、执行次数。按消费者分类比按顺序背更有用。
| 字段 | 主要消费者 | 关键约束 |
|---|---|---|
| 用例路径 | 统计与检索 | 继承需求路径,不手工拼 |
| 测试名称 | 人 | 能识别对象和检查点,不含操作步骤 |
| 前置条件 | 执行器 | 必须可重建,不允许引用其他用例 |
| 操作步骤 | 执行器 | 只写动作,不写检查结果 |
| 预期结果 | 执行器 | 只写断言,不写操作动作 |
| 优先级 | 调度 | 高中低,决定执行顺序和裁剪 |
| 用例类型 | 分类统计 | 流程类、功能点类、报表统计类、界面类、报文接口类、批处理、其他 |
| 用例属性 | 数据选择 | 正常/异常 |
| 测试方式 | 执行通道 | 手工/自动化 |
| 执行次数 | 执行器 | 重复执行,用于验证幂等与状态叠加 |
“执行次数”这个字段看着多余,其实解决一类具体问题:有些缺陷只在重复执行时暴露——重复提交按钮、幂等接口被调两次、优惠券叠加领取、状态机被同一事件触发两遍。这类用例第一次执行通过、第二次执行失败,如果不显式声明执行次数,执行人默认跑一遍就勾选通过,问题就被掩盖了。
“测试方式”和“用例属性”是正交的,不能互相替代。一条异常用例既可能手工执行,也可能已经自动化;一条流程类用例同样如此。把“是否自动化”塞进用例类型里,会导致分类统计失真——某个模块的自动化率看起来很高,实际是流程类用例被错误归到了接口类。
3.3 前置条件禁止相互依赖:这条规定在防什么
指南里那句话很硬:“用例之间不允许相互依赖,例如将其他用例作为前置条件。”这条规定的实质是把用例定义成独立的执行单元,而不是流程步骤的容器。
允许依赖会带来四个连锁问题。第一是级联失败:前置用例失败,后续一串用例全部失败,报告上看起来像雪崩,实际只有一个缺陷,排查成本翻倍。第二是执行顺序被锁死,无法并行、无法乱序、无法只跑失败的那几条。第三是可重复性丧失,第二次执行时系统状态已经被第一次改变,结果不可比。第四是自动化无从下手,脚本没法表达“先跑另一条用例”这种依赖,除非把两条合并——那就退化成了流程脚本。
正确的做法是把前置状态写成可重建的数据准备,而不是“先执行用例 A”。造数脚本的关键是先清后插,保证幂等:
-- 前置条件落地成可重建的数据准备,重复执行结果一致 DELETE FROM t_contract WHERE contract_no = 'AUTO_PRE_0001'; INSERT INTO t_contract (contract_no, status, credit_limit, used_amount) VALUES ('AUTO_PRE_0001', 'EFFECTIVE', 100000.00, 100000.00);这段脚本对应“已有一笔生效合同且额度已用满”这个前置条件。先删后插保证无论跑几遍,起点状态都一样;status和used_amount是这条用例真正依赖的两个字段,其余字段走表默认值即可。这也解释了为什么“执行次数”字段和这条规定是配套的:只有前置条件可重建,重复执行才有意义。
3.4 四个正交维度:优先级、用例类型、用例属性、测试方式
这四个字段容易被混用,因为直觉上它们相关:正常流程通常是高优先级、功能点类、手工执行。但相关不等于等价,一旦把它们合并成一个字段,统计口径就废了。
优先级分高中低,对应的是执行顺序和裁剪策略:高是基本功能和关键路径,正常流程、页面要素正常输入属于这一档;中是功能完善类,异常流程、异常输入属于这一档;低是体验和辅助功能,页面元素显示属于这一档。这个分档的用途在版本末期特别明显——时间不够时按优先级裁剪,而不是拍脑袋砍。
用例类型对应的是测试对象分类,它直接决定用例的划分方式,这一点在下一节的划分原则里体现得最明显:流程类按场景拆,功能点类按检查点拆,报表统计类、界面类、报文接口类、批处理各有各的拆法。类型定错,拆法就错。
用例属性和测试方式相对简单,一个是检测方向(正常/异常),一个是执行通道(手工/自动化)。指南里提到自动化用例和功能用例应匹配,若自动化不能完全覆盖功能用例,就拆成多个互补用例集。这条针对的是一个隐蔽的漂移:两套用例描述同一份需求,需求变更时只改了其中一套,于是出现“自动化全绿但功能漏测”或者反过来。互补用例集的作用是让两套用例的并集等于功能覆盖,任何一条功能用例都必须能在自动化集里找到对应项或者显式标注为“仅手工”。
4. 步骤与预期结果的对应关系:一对一、多对一、多对多
4.1 一对多为什么会把用例变成不可判定的
指南用了一整张表来说明步骤与预期的对应关系,四种形态:一对一、多对一(多组操作一个预期)、多对多(多组操作多个预期,用编号绑定)、一对多(一组操作多个预期,明确不建议、原则上不允许)。
一对多的根本问题是无法记录中间态。一组操作触发三个断言,第一个断言失败时,后面两个还执行不执行?执行了可能产生脏数据,不执行则覆盖不完整。无论哪种选择,用例的终态都只有“通过/不通过”两个值,失败信息的粒度退化成“这组操作有问题”。更麻烦的是自动化:断言顺序被硬编码进脚本,顺序一变,结果就变。
拆分的代价是用例数增加,收益是可判定性和可定位性。指南对这个取舍的态度很明确:一对多不允许,多对多允许但必须用编号绑定。这个差别背后的逻辑是,多对多至少还能通过编号把每个预期追溯到具体步骤,而一对多连追溯的锚点都没有。
4.2 编号绑定:多对多怎么在文本里不失真
多对多在实际业务里绕不开。一次表单提交可能同时触发字段级校验和业务规则校验,多组操作也可能汇聚到同一个结果。编号绑定是纯文本环境下的折中方案:给步骤编号,给预期编号,并在预期里写明依赖哪几步。
| 步骤 | 操作 | 对应预期 | 检查点 |
|---|---|---|---|
| S1 | 分类名称输入为空,点击添加 | E1 | 提示名称不能为空,添加失败 |
| S2 | 分类名称输入超长字符串,点击添加 | E2 | 提示名称超长,添加失败 |
| S3 | 分类名称输入已存在的名称,点击添加 | E3 | 提示名称已存在,添加失败 |
| S4 | 分类名称输入合法值,点击添加 | E4 | 添加成功,列表出现新记录;后台对应表新增一条记录且字段值与输入一致 |
这个表里 S1 到 S3 的预期都是失败路径,S4 是成功路径。S4 的预期里其实含多个检查点(前端列表、后台表记录、字段一致性),指南允许这种写法,但要求“一个预期结果分支含多步骤时,可先将步骤按序列出后,将检查点与其前置依赖步骤通过编号关联”。这句话翻译过来就是:预期可以长,但每个检查点必须能指回它依赖的步骤,不能出现“预期里描述了一个没人做过的操作”。
多对多的反面那行,指南写的是“多个预期结果中含多个检查点,不建议使用,尽量将此类用例按预期结果分支进行拆分”。这类用例是维护成本的重灾区:改一个字段,要在四五个预期分支里同步修改,改漏一处就出现前后矛盾。
4.3 关注点分离:步骤里不写检查结果,预期里不写操作
指南两条规定对着看很有意思:操作步骤中不能包含检查结果,预期结果中不能包含操作步骤。这不是文字洁癖,是执行模型的要求。
步骤是输入,预期是断言。混在一起会同时破坏两件事。对人工执行来说,步骤里写“点击保存,确认提示成功”,执行的人点完保存、看到页面没报错,就会顺手勾通过,那个“提示成功”的文案是否准确、是否被前端截断,没人细看。对自动化来说,脚本需要把每个动作映射成一个可执行指令,动作里夹着断言,解析器要么报错要么静默跳过,两种结果都不好。
预期结果这一侧的要求更细。指南要求前端操作成功或失败,预期必须覆盖页面显示、提示信息、后台数据存储、前后端数据一致性四层;涉及后台数据存储或变更的,要明确具体数据表记录和关键字段取值变化;提示信息要写清关键检查内容;后台系统测试和涉及信息安全的前端操作测试必须包含输出日志和后台数据存储结果检查。
这四层是有顺序的:页面显示最容易被验证也最容易被伪造,提示信息次之,数据库记录是事实来源,前后端一致性是最终判据。只验第一层的用例,在“接口返回成功但事务没提交”这类缺陷面前完全失效。而“明确具体数据表记录和关键字段取值变化”这条,要求写用例的人真的看过数据库设计文档——这也是为什么第 2 章第三步不能跳过。
4.4 用一段校验脚本验证用例能不能被机器读
判断一条用例写得规不规整,有个简单办法:看它能不能被一段几十行的脚本解析。下面这个检查器覆盖了指南里最容易违反的四条规则。
ASSERT_HINTS = ("确认", "检查", "验证", "应显示", "应提示", "看到") ACTION_HINTS = ("点击", "输入", "选择", "提交", "打开", "登录") def lint_case(case: dict) -> list[str]: """按指南口径检查一条用例的结构合法性""" issues = [] step_ids = {s["id"] for s in case["steps"]} refs = [e["step_ref"] for e in case["expects"]] # 规则一:每个预期分支必须挂在真实存在的步骤上 for e in case["expects"]: if e["step_ref"] not in step_ids: issues.append(f"预期{e['id']}引用了不存在的步骤{e['step_ref']}") # 规则二:一组步骤对应多个预期,属于一对多,应拆分 if len(case["steps"]) == 1 and len(case["expects"]) > 1: issues.append("单组步骤对应多个预期,属于一对多,应拆成多条用例") # 规则三:步骤里不应出现断言词 for s in case["steps"]: if any(w in s["action"] for w in ASSERT_HINTS): issues.append(f"步骤{s['id']}疑似混入断言:{s['action']}") # 规则四:预期里不应出现操作词 for e in case["expects"]: if any(w in e["content"] for w in ACTION_HINTS): issues.append(f"预期{e['id']}疑似混入操作:{e['content']}") # 规则五:正常用例的预期应能追溯到后台校验,而非只有前端提示 if case["case_attr"] == "正常" and not any("表" in e["content"] or "记录" in e["content"] for e in case["expects"]): issues.append("正常用例的预期未涉及后台数据校验") return issuesASSERT_HINTS和ACTION_HINTS是两套关键词表,按团队实际用词扩充即可,宁可多报也不漏报——检查器的定位是提示而不是判决。规则二实现的是指南里“一对多不允许”那条,判断条件写成“只有一组步骤且预期多于一个”,因为一对多的本质就是单组动作产生了多个互不依赖的断言。规则五对应“涉及后台数据存储与变更必须检查”,它是最容易被忽略的一条,因为前端提示肉眼可见,数据库记录要看日志或者查表,人工执行时往往被跳过。
这段代码的实际用途不止于检查。能通过它的用例,基本可以直接映射成自动化脚本的步骤数组和断言数组;通不过的用例,就是自动化改造时必然卡住的那批。
5. 避坑与排查:五个高频问题
5.1 颗粒度失衡:拆到输入框级别,或者一条用例包住整个流程
现象:某个模块的用例数上千条,回归跑不完只能抽样;另一个模块只有二十几条,缺陷全漏在分支上。
原因:划分维度选错了。指南的划分原则按测试对象分类给出不同拆法,前端功能按检查点拆(页面要素、列表查询分页删除、表单输入项),业务流程按场景拆(全流程一条、步骤分解若干),批处理按节点拆,数据埋点按页面拆。用功能的拆法去拆流程,就会拆出一堆“点击下一步”的空壳用例;用流程的拆法去拆功能,就会把十个输入项塞进一条用例。
解决:写用例前先确定这个测试对象属于哪一类,再查对应的拆法。前端功能的表单输入项还有一个弹性条款——视输入项数量而定,可酌情按输入项或输入分区划分,这意味着输入项少于五个时合并成一条是合理的,超过十个还合并就是偷懒。
5.2 前置条件写成“依赖上一条用例”
现象:单独执行任意一条用例(除第一条外)全部失败,必须按顺序整批跑才通过。
原因:把用例当成了流程步骤的容器,前置条件写成“先执行用例 A 完成注册”。这违反前置条件独立性要求,也让用例无法单独回归。
解决:把前置状态翻译成数据准备。有特殊账号权限要求的,写清角色和权限点;需要数据准备的,先清后插保证幂等;需要前置操作的,把操作写成脚本而不是另一条用例。判断标准很简单:把这条用例发给一个没参与编写的人,他能不能只靠前置条件描述就把环境准备好。
5.3 预期结果只写“操作成功”
现象:线上出现前后端数据不一致,回头查用例,发现相关用例全部通过。
原因:预期结果停留在第一层(页面显示)甚至第零层(没报错就算成功)。指南要求的四层——页面显示、提示信息、后台数据存储、前后端一致性——只覆盖了最外层。
解决:给正常路径的用例定一条硬规则,预期里必须出现至少一个可验证的后台事实,比如“XX 表新增一条记录,status字段为EFFECTIVE,amount与输入一致”。后台系统和涉及信息安全的前端操作,还要加上输出日志检查。这条规则会让写用例的速度明显变慢,但它拦下的正是那些“用例全绿、线上出事”的场景。
5.4 兼容性和数据埋点照搬功能用例的拆法
现象:兼容性用例数等于机型数乘功能点数,几千条没法执行;或者埋点只测了新增埋点,老埋点在某次改版后悄悄失效。
原因:这两类对象的划分维度和功能完全不同。兼容性按指定测试维度拆(移动端操作系统、机型、浏览器),数据埋点按页面拆(每个页面对应一条用例)。
解决:兼容性先定维度再拆用例,按操作系统维度就是两条,按机型维度就是机型数量条,不要和功能点做笛卡尔积。埋点除了新增埋点的检查,还要保留原有埋点的回归检查——改版最容易出的事不是新埋点没上报,是老埋点在重构中丢了。
5.5 需求变更只改用例,不改需求路径
现象:路径树和用例对不上,覆盖率统计失真,同一功能出现两套重复用例。
原因:改一条用例的成本很低,改需求树会牵动统计口径和别人的用例归属,于是大家下意识绕开。久而久之,需求树退化成历史遗迹,没人再信它。
解决:把变更顺序固定下来——先改需求树,再改用例。用例路径是从需求路径继承来的,需求树一改,受影响的用例路径自动跟着变,不会出现孤立节点。指南里说用例路径是在需求路径基础上追加需求名称,这个继承关系就是为了让路径永远一致。
6. 覆盖度是一道成本题:为什么“写全”从来不是目标
覆盖度这件事,我早年理解得很朴素:能想到的都写上。后来发现这是个边际收益递减的函数。一条正常流程用例能拦下的缺陷远多于第十条异常输入用例,而第十条异常用例的编写和维护成本并不比第一条低。指南里那套优先级分档,本质上就是对这个函数的承认——高优先级保基本功能和关键路径,中优先级保功能完善,低优先级是体验和辅助功能,版本末期按档裁剪。
| 阶段 | 执行范围 | 判据 |
|---|---|---|
| 冒烟 | 高优先级中涉及主流程的部分 | 关键路径是否通 |
| 全量回归 | 高 + 中 | 功能完整性 |
| 版本末期或紧急发布 | 高 + 变更影响范围内的中 | 变更点是否被覆盖 |
| 上线后验证 | 高优先级 + 生产问题对应的补录用例 | 线上行为是否一致 |
这张表真正想说的是:用例的价值不在数量,而在失败时的定位速度。一条写得好的用例失败后会直接告诉你“哪个页面、哪个字段、哪张表、期望什么、实际什么”;一条写得含糊的用例失败后,你得重新复现一遍才知道发生了什么。我见过用例总数翻倍、平均缺陷定位时间却变长的团队,多出来的那部分用例全是一对多、预期只写“操作成功”的快餐货。
验证方法也很朴素。写完一批用例,挑三条发给没参与编写的人,让他只照用例执行,不许问。他中途停下来问“这里是什么意思”的次数,就是这批用例的隐藏缺陷数。另一个办法是跑第 4 章那段检查器,规则命中率高的用例集,自动化改造时的返工率基本也高。
从那以后我每次交付一批用例,都强制走一遍这个动作:随机抽三条让旁人盲执行,再跑一次结构检查。有这个习惯之前,我总觉得用例写给人看,读者会自己补全上下文;有这个习惯之后才明白,用例的读者既不会补全,也不该被要求补全。希望帮到你。
本文还有配套的精品资源,点击获取