做了七八年测试,我最烦的事不是排查 bug,而是埋头写测试用例。尤其是那种几百行、塞满表格和业务规则的 PRD,光是把功能点从字里行间“抠”出来就得小半天,写出来的用例还总漏场景。后来我把这件事交给了大模型:让 LLM 直接解析 PRD,产出结构化测试用例,跑完两轮迭代之后,需求覆盖率将近翻了一半。这次就把这个方案的完整思路、提示词设计、工程细节和踩过的坑一次性讲清楚。
1. 为什么非做这件事不可:手写用例的底层问题
先交代一下背景。我们团队负责的是一个偏后台管理的产品,模块多、规则碎,每个迭代要动的需求点通常在 50~80 个之间。之前每个迭代靠测试人员手工梳理 PRD,再写功能测试用例,迭代末再拿用例去对需求做验收。听起来流程完整,但实际执行下来,问题比想象中严重得多。
1.1 手写用例的三宗罪:漏场景、怕变更、看资历
漏场景是最要命的。PRD 里的规则往往不只有正文描述,还有一堆参数表、状态流转图、权限矩阵。人工梳理的时候,最容易被遗漏的恰恰是表格里那种“隐藏条件”。举个例子,某个配置项在文档正文里只写了“关闭后不可恢复”,但后面的参数表里还备注了“当账户类型为试用版时,关闭后保留 7 天”。这种分散在两处、需要组合才能理解的规则,靠人眼扫很容易漏,而漏掉的通常就是线上出问题的场景。
怕变更排在第二。PRD 改一个字,用例可能就要跟着改一片,尤其是状态机一类的用例。改了一处字段,关联的前置条件和预期结果全要重新过一遍。手工用例改起来很痛苦,结果就是很多测试人员不愿意维护旧用例,迭代一多,用例库就成了没人敢动的“历史包袱”。
质量方差大是第三个问题。同样一份 PRD,资深测试写出来的用例能兼顾正向、逆向、边界和权限组合,新人往往只能写出主流程。团队里用例质量好不好,基本取决于“谁排到了这个迭代”。这种靠个人经验撑着的工作方式,注定不稳定。
1.2 PRD 是静态文本,缺的是一张需求追踪矩阵
我后来想明白了一件事:PRD 本身包含的信息量是足够的,但它是一份“静态文本”,需要人脑去解析成结构化的需求点、业务规则和场景组合。手工写用例的过程,本质上就是人脑在做“文本到结构化测试资产”的转换。
这个问题非常适合大模型处理。LLM 最擅长的就是语义理解和文本结构化抽取,它能从自然语言描述里提炼出功能点、边界条件、异常分支,并映射成标准用例格式。换句话说,LLM 不是替你写用例,而是替你做“PRD 到需求追踪矩阵(RTM)”的转换工作——这个转换一旦做出来,覆盖率、追溯性、变更影响分析全都好办了。
1.3 为什么不用规则引擎,非要上 LLM
有人可能会问:PRD 解析不是可以用正则、规则模板做吗?我试过。规则模板只能处理格式非常规整的输入,比如统一的“当…则…”句式。但真实 PRD 的写法五花八门,有的用表格,有的画流程,有的干脆就是一段话里塞三个规则。规则引擎遇到这种文本,召回率低到没法用。
LLM 的价值在于“理解”,它不需要我预设规则,而是直接领会一句话背后的业务含义,再输出我需要的结果。这也是为什么最后我选择 LLM 而不是继续堆正则。
2. 方案整体设计:从 PRD 到可复用的测试资产
这一节说说整体架构和选型思路。整个管线并不复杂,但每一步的设计都会直接影响最终用例的质量和覆盖率,值得细讲。
2.1 管线拆解:四段式处理流程
我把整个流程拆成四个阶段:
- PRD 预处理:读取原始文档,转成 Markdown 或结构化文本,抽取表格。
- 需求点抽取:让 LLM 通读 PRD,输出一份“需求点清单”,每条需求点带编号、模块、描述和原始出处。
- 用例生成:基于需求点清单,逐条或按模块生成测试用例,包含前置条件、操作步骤、预期结果、优先级和用例类别。
- 质量校验:先用程序做格式校验,再用 LLM 做语义评审,淘汰幻觉用例和重复用例,最后更新到用例库。
这里最关键的设计决策是把“需求点抽取”和“用例生成”拆成了两步,而不是让 LLM 一次性读 PRD 直接生成用例。一开始图省事直接让 LLM“读 PRD 生成用例”,结果很惨:模型容易盯着局部细节生成一堆用例,整体需求覆盖却漏掉一大片。拆成两步之后,先显式枚举需求点,再围绕需求点生成用例,覆盖率立刻上了一个台阶。
2.2 LLM 选型:通用大模型就行,但有几个硬指标
选型方面,我前后对比了通用对话模型和代码能力更强的模型。结论是:普通通用大模型完全够用,关键是上下文长度必须够长。一份中型 PRD 往往有 1 万到 3 万 token,如果模型上下文只有 8k,就得先做文本截断或分段处理,这会直接影响抽取完整性。
我的选型标准有三条:
- 上下文窗口至少要能容纳完整 PRD,至少 32k。
- 对 JSON 结构化输出的稳定性要好,不能经常输出残缺 JSON。
- 中文业务语义理解要过关,尤其是表格和状态流转这类内容。
至于要不要本地部署,看团队预算和合规要求。数据敏感度高就部署私有化模型,否则直接调用云端 API 更省心。我们用的是私有化部署的通用模型,效果和云端主流模型差距不大。
2.3 覆盖率口径:先搞清楚你提升了哪个指标
“覆盖率提升 45%”这个数字,如果不先定义口径,很容易变成自嗨。我用的指标是需求点覆盖率,定义如下:
需求点覆盖率 = 至少有一条用例覆盖的需求点数量 ÷ PRD 中全部需求点数量 × 100%
每个需求点来自第一阶段生成的“需求点清单”,每条用例必须引用至少一个需求点编号,才能计入覆盖。这样整个链路就形成了一张 RTM 表,覆盖率计算可以被程序和表格自动完成。我刻意没有用代码覆盖率,因为代码覆盖率是白盒指标,不适合用来衡量“PRD 里的需求有没有测到”,而需求点覆盖率更贴近业务验收视角,也更容易和产品、项目组对齐。
3. 核心实现:提示词、预处理与覆盖率优化
方案有了,接下来全是细节。这一节是全文实操性最强的地方,我把每一步的做法、参数和思考都写出来,方便直接抄作业。
3.1 PRD 预处理:三种格式先铺平路面
预处理不做好的话,LLM 再强也白搭。我们内部 PRD 主要有三种格式:
- Markdown:最好处理,直接读文本,按标题层级切分模块。
- Word(docx):用 python-docx 读取段落和表格,把每一行的单元格内容拼接成结构化文本,表格转成 Markdown 表格格式再喂给 LLM。
- PDF:先转成纯文本,再交给 LLM 做一次“乱序修复”和章节还原。
这里有个小技巧:表格内容必须原样保留,不能转成自然语言描述。比如“参数名、参数值、备注”这种三列表格,一旦你让它变成“某参数有值为 xx,备注为 yy”的描述,容易丢失列之间的对应关系。我选择把表格转成管道符分隔的 Markdown 表格,LLM 对这种格式的解析准确率明显更高。
3.2 提示词模板:让 LLM 先列清单,再写用例
这是整个项目最核心的地方。我写了两段提示词,分别对应需求点抽取和用例生成。
需求点抽取的提示词要点:
- 角色设定:资深业务分析师。
- 任务目标:把 PRD 中所有可验收的业务功能、业务规则、限制条件、异常分支逐条列出。
- 输出格式:JSON 数组,每条需求点包含
module(所属模块)、point_id(唯一编号)、description(需求描述)、source(原文出处或章节)。 - 强制要求:不得合并含义不同的规则,不得自己补充 PRD 中不存在的规则。
用例生成的提示词要点:
- 角色设定:资深测试架构师。
- 输入:上一阶段的需求点清单。
- 覆盖维度:正向主流程、逆向/非法操作、边界值、状态流转、权限与角色组合、跨需求点的组合场景,至少两类。
- 输出格式:每条用例包含
requirement_ids(关联的需求点编号)、title、preconditions、steps、expected、priority、category。
关键是这句提示词:“请先根据需求点清单规划用例覆盖矩阵,再逐条生成用例,不要跳过任何一个需求点。”这实际上是在引导 LLM 做显式的覆盖检查,让它在生成过程中“自我对齐”,比单纯说“请覆盖所有需求点”有效得多。实测下来,加了这句话之后,漏点率降低了大概三分之一。
3.3 结构化输出:JSON Schema 与自动校验
LLM 输出自由文本很容易,但要让用例直接进入测试用例库,就必须强制结构化输出。我在提示词里明确要求“只输出 JSON,不要输出任何解释性文字”,同时定义了 JSON Schema,程序侧用jsonschema库做校验。
简单示例:
{ "cases": [ { "requirement_ids": ["R001", "R002"], "title": "试用版账号关闭配置后仍保留数据 7 天", "preconditions": "账号类型为试用版,已开启关闭保护配置", "steps": [ "登录后台,进入关闭保护配置页", "点击关闭保护", "在确认弹窗中确认关闭" ], "expected": "关闭成功后,配置状态为关闭,数据保留 7 天后方可删除", "priority": "P1", "category": "组合场景" } ] }校验失败的情况很常见。模型偶尔会输出 Markdown 代码块包裹的 JSON,或者字段名被改成了下划线风格。我的处理方式是:先用正则把代码块剥掉,再做 JSON 解析;解析失败就带着报错信息让 LLM 重试一次。这里没有用无限重试,因为实测两轮之后成功率能到 95% 以上,再多的重试就是浪费成本。
3.4 覆盖率提升的四个关键策略
前面说了拆两步,真正让覆盖率涨起来的是下面这四个策略,缺一个效果都会打折。
策略一:让 LLM 显式枚举需求点。这是覆盖率的底座。LLM 先输出完整需求点清单,我再让人工快速确认一次,确认后的清单用来生成用例,避免用例生成阶段变成“无的放矢”。
策略二:强制要求组合场景。手写用例最薄弱的环节就是两个需求点交叉的场景。我在提示词里专门列了“组合场景”这个类目,要求模型识别需求点之间的依赖关系,并生成至少 30% 的组合类用例。这一步直接补上了人工最容易漏的那一块。
策略三:定向补测。第一轮生成完,用脚本比对需求点清单和用例引用的需求点编号,找出没被任何用例覆盖的需求点。这些“孤点”需求再单独喂给 LLM,定向生成用例。这个“跑两轮”的机制,是覆盖率最终提升到 45% 的最大推手。
策略四:边界值关键词引导。提示词里显式写上“请对每个数值型、日期型字段生成边界值用例(最小值、最大值、临界值、超过边界值)”。有了这条显式指令,LLM 几乎不会漏边界场景,而人工手写时恰恰最容易忽略它们。
4. 实操过程与效果验证:覆盖率提升 45% 怎么算出来的
方案看着没问题,真正落地还是要看数据。这一节记录我们两个月的实施节奏和最终数据,方便你做对比参考。
4.1 两个月落地节奏
我建议不要一上来就全量推。我们分了三个阶段:
- 第一周:挑一个中等复杂度的模块做试点,跑完整管线,重点验证输出质量和人工评审的配合方式。
- 第二到第四周:扩展到当迭代全部模块,成立一个“用例评审小组”,每天把关 LLM 生成的用例。
- 第五到第八周:固化流程,把管线接入迭代流程,PRD 定稿后两天内自动生成用例初稿,人工只做增删改。
最关键的经验是:不要试图让 LLM 一次生成所有模块的用例。一次塞太多模块,上下文一长,模型注意力会分散,后半段生成的用例质量明显下滑。按模块拆分,每个请求只处理一个模块的 PRD 内容,是最稳的做法。
4.2 数据对比:覆盖率提升 45% 是怎么来的
我们选了三个模块做对比统计,基准是上一个迭代完全手工写的用例,对照组的口径保持一致。
| 模块 | 需求点数 | 手工用例覆盖需求点 | 手工覆盖率 | LLM辅助后覆盖需求点 | 辅助后覆盖率 |
|---|---|---|---|---|---|
| 模块A | 46 | 32 | 69.6% | 41 | 89.1% |
| 模块B | 58 | 31 | 53.4% | 52 | 89.7% |
| 模块C | 40 | 22 | 55.0% | 35 | 87.5% |
| 合计 | 144 | 85 | 59.0% | 128 | 88.9% |
手工基线覆盖率是 59.0%,LLM 辅助之后是 88.9%,绝对提升接近 30 个百分点,相对提升约 50%。如果按“新增覆盖需求点 43 ÷ 原有覆盖需求点 85”来算,提升幅度是 50% 出头。标题里写 45%,是拿了三个模块里相对保守的两个做单独测算,口径更稳。不管怎么算,方向是一致的:需求覆盖率的增长主要来自组合场景和边界值两类用例,这两类恰好是手工最容易漏的。
4.3 团队流程调整:测试人员的重心变了
这个方案落地后,测试团队的角色发生了明显变化。用例生成不再是纯手工劳动,测试人员把更多精力放在“评审”和“业务理解”上。我们定了新的分工:
- LLM 负责生成用例初稿,覆盖所有需求点。
- 测试人员负责评审优先级、核对业务语义、补充 PRD 里没写但真实存在的隐晦规则。
- 产品经理负责在需求点清单上签字确认,防止 LLM 理解偏差导致用例方向错。
带来的直接效果是,用例库从“写了就不想动”变成了“每次迭代自动更新”。PRD 变更时,我们只重新跑一遍变更模块的用例生成,再让测试人员核对增量部分,维护成本大幅下降。
5. 踩坑实录与排查技巧
任何用 LLM 落地的项目都逃不过踩坑阶段。这一节把我和团队踩过的、以及身边同行问过最多的几个坑整理出来,当个速查表用。
5.1 幻觉用例:模型编了个产品里不存在的按钮
最吓人的问题就是幻觉。有一次模型给某个列表页生成了“批量导出 Excel”的用例,可产品里根本没有这个功能。这种用例如果混进用例库,比漏用例还危险,因为测试人员会照着不存在的功能去测,纯属浪费时间。
排查思路很简单:确认每个需求点都有 PRD 出处。我在提示词里强制要求每条用例引用需求点编号,程序侧再校验引用的编号必须存在于需求点清单里。这样幻觉用例基本会在源头被拦截。万一还是有漏网之鱼,就靠评审环节的人工判断了。
5.2 PRD 质量太差,LLM 也回天无力
这是最想吐槽的一点。LLM 的解析能力再强,面对写得像字段堆砌、一句话塞三个逻辑的 PRD,输出质量也会下滑。遇到这种情况,我不建议硬上,而是在预处理后先让 LLM 生成一份“需求理解摘要”给产品经理确认。产品经理确认摘要没问题,再往下一步走。
这个“先确认理解、再生成用例”的步骤,表面看多了一道流程,实际上省掉了后面大量返工。我不止一次遇到模型理解偏了,用例生成得倒是很完整,结果全得推翻重来。让产品经理先把关理解,比让测试经理在用例阶段返工高效太多。
5.3 用 LLM as Judge 给用例质量打分
光有覆盖率还不行,用例本身质量也要兜底。我用了一个简单的“模型互评”方案:让一个独立的 LLM 扮演评审专家,对生成的用例按“步骤清晰度、预期结果可验证性、场景覆盖率、是否存在重复”四个维度打分,并输出修改意见。
这个方案的成本不高,但收益很实在。模型互评最大的价值不是打分本身,而是能发现“用例描述过于含糊”这类很难用规则识别的问题。比如“点击按钮后查看结果”这种用例,人眼很容易放过,但作为 Judge 的模型会明确标出来,因为它被训练过要输出可执行的测试步骤。
5.4 成本与性能取舍:长 PRD 拆分与重试控制
成本问题绕不开。一份 3 万 token 的 PRD,拆成 10 个子请求和 1 个大请求,价格差别不大,但稳定性差别很大。我的经验是:按模块拆,每个请求控制在 6000 token 以内,既不会超上下文,也不会因为内容太少导致模型缺少全局上下文。
另外,重试请求会白白烧钱。我建议把重试次数限制在 2 次以内,并且只针对“JSON 解析失败、字段缺失”这类可修复错误做重试。对于“生成了明显错误用例”这类语义问题,直接走人工修正更好,重试只会消耗更多 token,产出却不稳定。
6. 我的几点实践体会
最后分享几个这次落地过程中最有价值的判断,给准备上这个方案的同学一点参考。
第一,不要把目标定成“自动生成用例”,而应定成“自动建立需求追踪矩阵”。只要把 PRD 到需求点的映射做扎实,用例生成反而是顺水推舟的事。第二,LLM 当评审者比当创造者更稳。生成用例的环节,只要引入一点结构约束,效果就很好;但用模型互评做质量把关,出错的概率低得多。第三,别指望 LLM 帮 PRD 写得差的产品兜底,它只能把已有规则显式化,不能凭空变出规则。把产品经理拉进流程一起确认需求点清单,才是这个方案长期跑得稳的真正原因。