
做软件测试这些年我面试过不少人也带过不少新人。几乎每个来面试的人都会说自己“会写测试用例”可真正到了项目里能把用例写到“可直接执行、能发现缺陷、能沉淀复用”这个水准的比想象中少得多。测试用例的设计看起来是软件测试里最基础的一项技能但它恰恰决定了整个测试过程的天花板用例设计得粗漏测就是必然用例设计得僵执行就成了体力活用例设计得散后期维护能把你耗死。这篇文章我想把自己实际写用例、审用例、教别人写用例的完整思路整理出来不空谈理论每一块都尽量落到能直接用的层面。适合刚入行的功能测试、准备测试面试的转行者以及开始带测试团队的组长参考。1. 测试用例这件事先把它想透再动手很多人写用例之前没有想清楚一个问题我写这套东西到底要用来干什么如果只是为了应付“测试计划阶段必须产出用例”这个流程那写出来的东西大概率是废纸。测试用例的本质是把需求转换成一组可执行、可判定、可追踪的验证活动。它的价值不是“存在”而是“被使用”。1.1 一份用例到底值在哪里我习惯把用例的价值拆成五个角色这五个角色在项目不同阶段体现得不一样执行脚本把“要测什么”翻译成“怎么测”。这是最直观的价值尤其当执行人不是用例作者本人的时候一份好用例就是一份可照做的手册。覆盖度量通过用例数量、分布、类型结合需求跟踪矩阵可以量化测试进度和需求覆盖情况。领导问“测完了吗”你不能只拍胸脯得能指出哪条需求对应哪几条用例、执行结果如何。回归基线版本迭代时旧功能不能回归。用例就是基线没有基线每次发版都靠人脑回忆老逻辑迟早出事。知识沉淀老功能换新人接手时项目文档可能早就不更新了但用例通常还活着。用例是离代码最近的“活的规格说明”。沟通契约产品和开发、测试和开发之间需要就“这个版本测什么、不测什么、什么算对”达成一致。用例评审就是一种契约确认方式。这五个角色不需要每套用例都占满但你动笔之前得知道自己这一版用例重点服务哪个角色。比如敏捷迭代里可能不需要花哨的用例模板但回归基线必须留好传统V模型项目里用例评审和覆盖度量就很重要。1.2 什么时候写用例、写多细不是拍脑袋定的不同场景对用例的编写时机和详细程度要求完全不同。我见过最典型的冲突是从传统企业项目跳到互联网敏捷团队的人抱怨团队不写用例而敏捷团队的人觉得写了也没空看因为需求天天变。其实两边都对关键是把用例的“形态”拉开。传统项目V模型、W模型测试计划阶段就要完整编写用例经过评审冻结执行时原则上不随意改。用例要全字段要规范步骤要细一份用例可能对应一个正式提交记录。敏捷迭代用例往往跟着需求故事卡走。迭代初先用XMind列测试点开发提测前补细关键路径用例回归用例则持续沉淀。重点不是“写满”而是“把风险和边界覆盖住”。探索性测试不预先写全用例用思维导图和测试笔记边测边记探索结束把发现的问题和补充场景反哺成用例。探索测试不是不写用例而是用例生成在探索之后。纯回归测试用例宁多勿漏它是发版安全网。这种场景下用例的维护价值最高因为大概率会被反复执行。用例的“厚度”也取决于风险和测试目标一个新功能首版上线用例要覆盖主流程、异常流、数据边界、权限、兼容性一个内部管理后台的某个列表页新增排序字段用例有一组正向场景加一组空数据场景就够了没必要为它写出一本百科全书。先想清楚场景再决定写多细这才叫设计。2. 写用例之前的需求拆解这一步最容易被跳过我审过很多新人的用例最常见的问题不是方法不会用而是需求没吃透就直接开写。等用例评审的时候开发问一句“这个字段下拉选项的数据源是什么”当场就卡住。需求拆解不是废话它是用例设计真正要花时间的地方。2.1 从PRD里提取测试点的四个具体动作拿到一份PRD别急着打开用例管理工具先做四个动作读、问、拆、标。读完整通读需求把功能清单、业务规则、限制条件、异常提示语全部圈出来。注意是“所有”——包括文档角落里的边界说明、状态流转图里的每个分支、接口文档里的每个参数约束。问把需求里那些“应该”“可以”“尽量”的模糊表达全部找出来问产品。比如“密码要比较复杂”“复杂”是什么标准比如“超时后订单取消”超时是多少分钟取消前有没有提醒取消后库存是否回滚这些问题不确认清楚用例没法设计。拆把大功能拆成独立可测单元。拿最常见的登录功能举例至少能拆出输入校验、认证逻辑、会话管理、错误提示、安全性、兼容性这几个单元。每个单元再往下拆子项。拆得越清楚用例的边界就越清晰。标标出高风险区域。涉及金额、权限、并发、数据一致性、对外接口、支付回调这些功能务必在测试计划里标红用例数量分配要向它们倾斜。一个普通列表页和一个支付模块用同样的用例密度是不合理的。2.2 用XMind梳理测试点比硬憋用例高效得多画思维导图是我见过的最高效的用例前置动作。它不需要受用例模板字段的约束可以快速把脑子里的测试点全部倒出来。以登录功能为例我会先画出这样的结构登录 ├── 输入校验 │ ├── 用户名格式 │ ├── 密码规则 │ ├── 空值 │ └── 特殊字符 ├── 认证逻辑 │ ├── 正确账号密码 │ ├── 错误密码 │ ├── 不存在账号 │ └── 账号锁定策略 ├── 会话管理 │ ├── 记住我 │ ├── 会话超时 │ └── 多端登录 ├── 错误提示 │ ├── 用户名错误提示 │ ├── 密码错误提示 │ └── 账号锁定提示 ├── 安全性 │ ├── 密码传输加密 │ ├── 密码存储加密 │ └── 防暴力破解 └── 兼容性 ├── 不同浏览器 └── 不同分辨率这个思维导图有两个好处第一评审时对着导图过一遍大家看的是测试思路而不是用例细节沟通效率高第二导图里每一个叶子节点映射到用例编号需求变更时能快速定位哪些用例要动。我带的团队现在所有的测试计划评审第一版都是导图导图通过后才生成正式用例。2.3 需求变了用例怎么跟着变需求变更不是测试用例的敌人真正的问题是需求变了用例没变。我见过一个项目需求从“只能绑定一张银行卡”改成“最多绑定三张银行卡”用例库里还全是单卡的场景结果回归时旧数据和新逻辑的冲突完全没被覆盖到。应对办法是维护一张“需求—测试点—用例”的映射表。每次需求变更先做影响分析被改动的模块有哪些关联的上下游模块有哪些数据兼容性是否受影响提示语和状态流转是否跟着变。然后对映射表里的用例执行四个动作之一新增、修改、标记废弃、安排回归冒烟。这张映射表不复杂Excel里就能维护但它的价值在版本迭代到第10个的时候会体现得非常明显——谁维护了它谁就掌握着项目的测试脉络。3. 等价类与边界值性价比最高的方法组合如果只允许我用两个方法设计用例我会毫不犹豫选等价类划分和边界值分析。这俩不是最炫的方法但它们的投入产出比极高几乎适用于所有输入型功能。我经常跟新人说先把这两个方法练到形成肌肉记忆再去谈场景法判定表那些花活。3.1 等价类划分不是把输入随便分个组等价类划分的核心逻辑是把输入域划分成若干个子集同一个子集里的任何输入值对发现缺陷来说效果是等价的所以只需要从每个子集里挑选一个代表值设计用例。这句话很多人背得熟但用的时候有两个问题。第一个问题只设计有效等价类不重视无效等价类。绝大多数新人的用例覆盖了所有合法输入的路径却漏了大量非法输入的路径。可实际线上报出来的bug恰恰集中在用户输错、乱输、传空值这些场景里。无效等价类不是配角它和有效等价类同等重要。第二个问题不知道什么时候不能用等价类。如果输入条件之间有关系比如“用户名不为空且长度不超过20且格式为邮箱”这不是一个简单的等价类得拆成多个条件分别划分再配合判定表处理组合关系。举个例子手机号输入框。有效等价类可以是“11位数字且以1开头”无效等价类包括空值、10位数字、12位数字、包含字母、包含特殊字符、以非1开头。注意这里的“以1开头”是否要限制第二位为3、4、5、6、7、8、9取决于需求怎么定这就是需求拆解阶段要确认的规则不能自己拍脑袋。3.2 边界值上点、离点、内点要说清楚边界值分析是基于一个事实开发人员在写判断条件时最容易在边界附近犯错。小于等于还是小于这个等号一错边界值就翻车。而缺陷往往藏在边界的“附近”所以边界值要单独作为测试点来设计。关于边界值面试经常问“上点、离点、内点”的定义实操中要把它们对应到具体的值上上点边界上的点。比如需求是“密码长度6到20位”6和20就是上点。离点离边界最近的点。闭区间[6, 20]的离点是5和21因为5刚好小于621刚好大于20。内点有效输入域内的点通常取一个中间值比如12。有一个容易搞混淆的地方开区间、半开半闭区间的离点选择会变化。有时候需求描述是“输入值必须大于0且小于等于100”那么1是内点100是上点0和101是离点还是边界外的点这时候最好把区间画出来一个一个点列清楚别用脑子空想。设计用例的原则是上点和离点必测内点视情况抽测。3.3 一个完整例子用户注册密码输入框拿一个典型需求练手密码长度6到20位必须同时包含字母和数字不能包含连续3个相同字符区分大小写。这份需求看起来不复杂但把等价类和边界值联合用上用例可以设计成一串用例编号输入值预期结果优先级PWD-TC-001a15位提示长度不足高PWD-TC-002a1b2c36位校验通过高PWD-TC-003a1b2c3d4e5f6g7h8i9j0k20位校验通过需满足字母数字规则高PWD-TC-004a1b2c3d4e5f6g7h8i9j0k121位提示长度超出高PWD-TC-005abcdef纯字母提示必须包含数字中PWD-TC-006123456纯数字提示必须包含字母中PWD-TC-007aa1234连续3个相同字符提示不允许连续相同字符高PWD-TC-008a12a12无连续相同字符校验通过中PWD-TC-009A1b2C3区分大小写场景校验通过且不同大小写视为不同字符中PWD-TC-010空值提示密码不能为空高PWD-TC-011ab123包含特殊字符取决于需求是否允许需确认低PWD-TC-012密码中包含中文取决于需求通常拒绝低这套用例可以清晰看出等价类和边界值的分工长度规则用边界值覆盖5、6、20、21字符组成规则用等价类覆盖纯字母、纯数字、字母数字组合连续重复规则用特殊等价类覆盖。一套用例把高优先级的规则边界全部锁住剩下的交给场景方法和业务经验去补。4. 场景法、判定表与正交试验面向流程和组合的进阶打法等价类和边界值解决的是“单个输入条件”的问题但实际项目里还有两类情况它们罩不住一是业务流程跨步骤缺陷只有在走到第五步的时候才爆炸二是多条件组合条件一多全组合用例数量让人绝望。这时候需要上场景法、判定表、正交试验这些方法。4.1 场景法按照用户真实操作路径设计用例场景法适合测那些有明确流程的功能比如下单、支付、审批、开户、退款。它的核心是先画出基本流和备选流基本流就是用户从起点到终点正常完成业务的路径备选流则是各种分支、异常、回退路径。我拿ATM取款举例。基本流是插卡→输入密码→选择取款→输入金额→出钞→取卡结束。备选流包括密码错误、密码连续错三次卡被吞、余额不足、超过单笔取款上限、取款机里没钱、超时未取卡、取消交易退卡、卡被遗忘后系统回收。很多团队只测基本流这是漏测的重灾区。业务流程里的状态之间的互相制约比如“转账中”和“转账成功”之间有没有中间态、“订单已支付但支付回调还未到达”之间用户看到什么这些必须靠场景法把流与流之间的岔路口全部拉出来测一遍。场景法还有一个好处是能让用例阅读者快速理解业务全貌不会只见树木不见森林。4.2 判定表条件多、组合多时用它收口当功能由多个条件共同决定动作时判定表就是最好的工具。它的结构是列出条件桩、动作桩、条件组合以及每种组合下的动作。我以“用户登录”为例假设条件是用户名是否正确、密码是否正确、账号是否锁定动作是允许登录、提示用户名或密码错误、提示账号已锁定。用户名密码账号状态结果正确正确正常登录成功正确错误正常提示密码错误错误正确正常提示用户名错误错误错误正常提示用户名或密码错误正确正确锁定提示账号锁定禁止登录正确错误锁定提示账号锁定禁止登录错误正确锁定提示账号锁定禁止登录错误错误锁定提示账号锁定禁止登录这个例子有3个条件、8种组合。判定表的优势是所有组合一目了然评审时对着表检查能快速找出逻辑冲突。它的劣势也明显条件数一多组合数指数上涨4个条件就是16种5个条件就是32种。所以判定表适合条件在3到6个之间的场景条件再多就要用正交试验来压缩用例量。4.3 正交试验用更少的用例覆盖更广的组合正交试验不追求穷举所有组合而是利用正交表的特性用少量测试用例覆盖“任意两个因素的所有水平组合”至少一次。它特别适合搜索条件、筛选器、报表维度这类高维度组合的验证。举个例子商品筛选有3个因子排序方式默认/价格/销量、价格区间有/无、库存状态有货/无货每个因子2个水平。全组合是2×2×28种用正交表L4(2^3)设计只需要4条用例就能覆盖任意两个因子的所有组合用例排序方式价格区间库存状态1默认有有货2默认无无货3价格有无货4销量无有货实际项目里因子可能更多水平也不一定齐有些因子之间还有约束关系比如“选择包邮后无需再选配送方式”。遇到这种情况可以手动调整正交表把无效组合剔除后补充有效组合。正交试验不是万能药但它能把组合类用例的数量从“测不完”变成“可控”值得掌握。4.4 错误推测法经验值就是测试用例的金矿错误推测法听起来不够“科学”但它产生的用例往往是质量最高的。它的本质是基于过去踩过的坑、线上故障、历史缺陷记录预测这个功能最可能在哪些地方出问题然后针对这些高风险点写用例。这不是玄学是经验积累的产物。常见的错误类型包括空值处理、超长输入、特殊字符、重复点击、并发提交、缓存数据不一致、时区转换、字符编码、权限越权、状态流转错乱、定时任务和人工操作冲突等。举例来说列表页翻页后筛选条件丢失连续点击提交按钮产生两条重复订单金额计算出现精度误差删除操作没加二次确认这些都属于错误推测法的典型产物。我建议团队里每个测试人员都维护一份个人的“缺陷敏感清单”每次测新功能之前对照清单过一遍。这份清单可能很杂但它是测试用例设计里最有“个人资产”味道的部分。规划用例时不要先只排正常流程先把这些“用经验抓出来的异常点”排进去它们才是执行时最可能捞到鱼的用例。5. 用例落地的规范化字段、颗粒度与可执行性方法再漂亮最终都要落到一份份用例里。我发现团队里用例设计水平不高的另一个原因是很多人压根没用过规范的用例字段。用例字段不是行政要求每个字段都有它存在的意义。5.1 用例字段怎么设计不同团队差别很大一份标准的测试用例通常包含这些字段用例编号、所属模块、用例名称、前置条件、测试数据、操作步骤、预期结果、实际结果、优先级、用例类型、执行人、执行结果、备注。每个字段都有作用用例编号唯一标识一般按“模块-类型-序号”命名比如“LOGIN-TC-001”方便追踪和引用。前置条件执行这条用例前必须满足的环境、数据、权限状态。不写前置条件执行人跑着跑着发现条件不满足只能停下来问人。测试数据明确写出具体的输入值不要写“合法的手机号”要写“13800138000”。操作步骤按顺序排列的、可执行的动作。每步用“点击”“输入”“选择”“等待”等明确动词开头。预期结果必须是可以判定的描述不能写“正常”“正确”要写“页面提示‘修改成功’并跳转列表页”“数据库中该记录状态变为1”这种可以被验证的结果。优先级高、中、低三级足够。优先级决定回归时用例被执行的先后顺序高优先级用例自然要排在冒烟里。不同团队对字段的要求差别很大敏捷团队可能只保留“前置条件-步骤-预期-优先级”这几个核心字段把用例当成轻量checklist用银行、证券、军工等合规性强的项目用例字段要非常全还要有评审记录、变更记录、执行截图等审计痕迹。所以不要迷信某一种模板关键是让字段服务于流程需求。5.2 颗粒度太细是负担太粗是摆设用例颗粒度是门艺术。颗粒度太细一个按钮拆出十几种交互执行人看步骤看到烦用例库膨胀到没人愿意维护最后全变成僵尸用例颗粒度太粗写上“验证登录功能正常”执行人看完不知道要做什么测不测全靠自觉。我个人的颗粒度参考标准是三条一条用例聚焦一个业务规则或一个验证目标操作步骤控制在3到8步一组用例的执行时间控制在5到15分钟内能跑完。如果一条用例的步骤超过10步我会考虑是不是拆成两条。注意这条标准主要针对手工用例自动化用例的拆分逻辑不同自动化为了定位失败点往往要求一个用例只做一件非常小的事。还有一个容易犯的错把多条相似的用例合并成一条“万能用例”。“输入用户名、密码按回车验证能登录”表面上覆盖了正常登录但需求里“用户名区分大小写”“密码错误连续5次锁定”这些规则都没有独立用例去体现最终覆盖率是虚的。5.3 能让新人照着手册跑可执行性的标准我一直坚持一个标准用例写完后团队里任何一个没有接触过这个需求的新人照着手册能独立执行完这条用例并且能判断结果是否符合预期。如果能做到说明可执行性过关如果做不到就是用例写得不够好。可执行性的几个检查点前置条件里账号密码、测试环境地址、数据准备方式是否写清楚操作步骤是否因果倒置比如“输入正确密码”但没有交代密码是什么预期结果是否出现主观模糊描述异常分支是否标明了“该步骤若失败则继续执行还是中止”。写用例时作者脑子里有需求的全部上下文很容易默认读者也知道实际执行的人往往什么都不知道。把自己放在“什么都不知道”的位置上写用例是提高可执行性最有效的心法。6. 用例评审、维护与复用写一次不是终点很多测试团队的用例库第一版是最完整的之后越做越烂最后变成没人看的死文档。问题出在缺了三个动作评审、维护、复用。这三件事没有做好用例设计得再好也白搭。6.1 评审到底评什么四个关注点用例评审不是走过场它应该解决四个问题。第一个是覆盖度每条需求是否都有对应的正向用例和反向用例高风险区域是否分配了足够的用例第二个是准确性预期结果是否和需求一致有没有把个人理解当成需求标准第三个是可执行性步骤是否清晰数据是否明确逻辑是否通顺第四个是重复与冲突多人负责同一个模块时用例之间是否重复描述是否存在矛盾。评审角色我建议这样安排测试负责人主审覆盖度和可执行性产品经理确认需求理解是否一致开发人员可以帮忙指出逻辑漏洞和接口边界。有些团队固定每周一次用例评审有些团队则只在需求变更较大时组织但不管频率如何评审结果要有记录、有结论、有修改负责人不然评了个寂寞。6.2 触发维护的四个信号用例维护的触发信号很明确遇到下面四种情况用例必须立刻更新需求变更需求文档改了用例不跟着改执行的就是错误基线。线上故障或漏测bug上线后出了事故复盘时发现某类场景没覆盖马上补用例防止下次再漏。新增边界条件或历史缺陷定位结论开发排查后告诉你“原来这个字段最大只能存255个字符”这属于新知识点要沉淀进用例。架构、UI或接口重构功能行为可能没变但操作路径变了前置条件可能也变了用例得同步调整。维护动作包括新增、修改、废弃三种。特别要强调的是“废弃”这个动作很多团队不做导致用例库里一堆失效用例新人执行时被误导。我要求团队每个月至少清理一次无效用例给它们打上“已废弃”标记而不是直接删除保留历史痕迹方便追溯重构前的测试基线。6.3 从用例库到测试资产复用策略用例复用不是“复制粘贴改个项目名”就行。同一模块在不同项目里的业务规则可能有差异直接把旧用例拿过来用容易带着旧项目的假设去测新项目。复用正确的做法是标准化把用例按功能域拆块块与块之间解耦比如“用户管理”“订单管理”“支付流程”各自独立。新项目来了先看哪些功能域相同再把对应的用例块拿过来逐一核对该项目需求调整测试数据和预期结果补充新的业务规则。更进一步成熟的团队会把用例资产化功能用例、接口用例、性能用例、兼容性用例分开管理手工用例和自动化用例之间建立映射关系手工用例转自动化时能追踪原始设计意图用例库和缺陷库打通每条用例关联它发现的缺陷未来可以分析哪类用例产出缺陷最多反向指导测试设计重点。走到这一步用例才真正成为团队的测试资产而不只是当次版本的一个附件。7. 用例设计里的常见误区和我个人的几条建议最后聊聊我这些年看过、踩过、教过的那些坑。写用例和写代码一样有些错只有吃过亏才能记住。7.1 我踩过的三个坑第一个坑用例照抄需求描述。我刚带项目的时候有同事写的用例是“验证系统可以根据用户类型展示对应的菜单”预期结果写“菜单展示正确”。这等于什么都没写。后来我要求每条用例必须先明确“用户类型是什么、菜单应该包含哪些项、不应该包含哪些项”用例才真正有判断标准。第二个坑追求数量忽略优先级。有一版用例我把所有边边角角的场景都写满了总数几百条执行时间排得满满当当。结果核心功能反而只分到一半的资源上线前发现主流程有个低级bug。从那以后我写用例先排优先级高优先级的用例里第一版就必须覆盖主流程、关键异常、权限、数据一致性低概率低影响的组合类场景放在后面宁可测不到也不能喧宾夺主。第三个坑写完了不更新。这个前面说过项目都发了好几个版本用例还停留在第一版后面执行用例纯属走流程。我现在要求每次发版后做一次“用例健康度检查”看哪些用例挂了、哪些没执行、哪些改需求后没有动几分钟的事但能把用例从僵尸状态里救回来。7.2 AI生成测试用例能不能用这两年AI生成测试用例越来越流行我自己的体验是它能提高从“需求文本”到“初步测试点”的效率但远没到“代替测试人员设计用例”的程度。工具生成用例的问题在于它通常会基于需求描述生成大量正向场景而对无效等价类、边界组合、业务状态流转、历史缺陷类型这些隐藏较深的部分覆盖薄弱。也就是说AI给出的东西往往“很全但没有灵魂”。我现在用AI的方式是先把需求描述和我梳理的XMind测试点喂给它让它补充候选用例然后我人工过滤、修改、补边界。它提供的用例我可以用来检查我自己的盲区但永远不会直接入库。测试用例是要拿去执行、要支撑发版决策的它的准确性必须由人来兜底这条底线不能退。7.3 心里要有一杆秤到了最后想明白一件事测试用例设计得再好也改变不了测试的“抽样”本质。任何项目的测试都不可能覆盖所有输入和所有组合你只能选择“最有价值的那批用例”去执行。所以心里那杆秤永远是“这次改动风险在哪、什么用例能最快发现致命问题、什么用例值得反复执行”。对我来说一份用例设计得好不好从来不看数量多少也不看模板多漂亮。我就看三件事第一执行它能不能高效发现缺陷第二版本迭代后它能不能快速更新并支撑回归第三换一个新人来能不能拿着它就上手。这三点做到软件测试的用例设计功夫就真正长在你自己身上了。