系列07-如何用 AI 从 PRD 批量生成功能测试用例?Vision 读图与章节分批实战

系列07-如何用 AI 从 PRD 批量生成功能测试用例?Vision 读图与章节分批实战

一份 40 页的 PRD,测试负责人往往要 2~3 天 拆功能点、写步骤预期,还要对齐禅道「产品 / 模块 / 研发需求 / 适用阶段」。直接丢给 AI大模型,常见问题不是「写不出来」,而是 写不稳

  • 第 15 页流程图里的校验规则 根本没进用例
  • 禅道 product 被 AI 编造成不存在的模块路径
  • 同一项目里,三个人用 AI 写,标题格式各一套

工程化做法不是「更大的 Prompt」,而是 解析 → 范围裁剪 → 双模型 → 结构化入库 → 平台注入元数据 。本文基于 BrickCore 需求测试中心(routers/ai/requirements.py + test_analysis.py)讲完整链路;设计思路可脱离具体平台复用。


演示与源码

地址
功能演示 http://43.142.83.156/showcase/ (「AI 需求 → 功能用例」含录屏;平台 admin / BrickCore123456)
开源仓库 https://gitee.com/BanZhuanKeOrz/BrickCore

线上菜单:AI 测试 → 需求测试中心。建议先看演示录屏,再按第九节实操。


一、AI大模型 单对话 vs 平台流水线

维度 单对话粘贴 PRD 平台流水线
上下文长度 易超 Token,只能手工砍章节 scope_section_ids 按章裁剪
内嵌图片 需截图逐张贴 Vision 读 PDF/Word 嵌入图
禅道字段 LLM 编造 product/module 平台绑定注入,不进 Prompt
标题规范 每次格式漂移 Jinja2 模板 + 语义槽位
可追溯 聊天记录 需求版本、批次、source_ref
大文档 一次失败重来 异步 Job 分批 + 进度轮询
质量约束 靠人盯 Prompt grounding + 禁止空洞表述

二、四层架构(从上传到导出)

复制代码
┌─────────────────────────────────────────────────────────┐
│ 1.  ingest   上传 PRD → MinIO 原文件 + 解析 document_structure │
│ 2.  scope    章节树 → 勾选范围 → estimate_scope(ok/warn/block) │
│ 3.  generate Vision 读图 → 正文+[图-N] 交错 → 文本 LLM → JSON  │
│ 4.  publish  Jinja2 标题 + 禅道绑定 → 表格编辑 → 导出 XLSX      │
└─────────────────────────────────────────────────────────┘

设计原则 :LLM 只负责 语义内容 (步骤、预期、模块槽位);元数据与格式 由平台配置,避免幻觉污染导入。


三、文档解析:章节树与原文保真

上传 PDF / Word / TXT / Markdown 后,解析器产出 parsed_content

字段 含义
sections 章节树(id、title、level、block_ids、image_indices)
blocks 正文块,与章节关联
image_count 内嵌图数量

原文件进 MinIOai-requirements bucket),结构存 DB;支持 reparse-document 换解析规则后重切章节,不丢原文件。

实操建议 :生成前打开章节树,确认「一级模块 / 二级功能」与 PRD 目录一致;错乱时优先换 Word/MD 或重解析,不要硬生成。


四、双模型:Vision 读图 + 文本 LLM 写用例

4.1 为什么必须双模型

模型 职责 不做
Vision(qwen-vl 等) 读流程图、原型、表格截图 → 结构化文字摘要 不直接输出完整用例表
文本 LLM(DeepSeek 等) 读「章节正文 + 图-N 摘要」→ JSON 用例数组 不读二进制图

纯文本模型对 PDF 内图片 无能为力 ;若范围含图却未配 Vision,Backend 直接 400(避免 silent 漏规则):

python 复制代码
# test_analysis.py --- _build_scoped_content
if image_count > 0 and not vision_config_id:
    raise HTTPException(
        status_code=400,
        detail=f"选中范围包含 {image_count} 张图片,请选择 Vision 模型配置",
    )

4.2 正文与读图如何合并

Vision 逐张分析后,build_interleaved_content正文块[图-N] 读图 JSON 按章节顺序交错拼进 Prompt。文本 LLM 看到的是「可引用的图内控件名、提示文案、布局」,而不是附件。

4.3 源码视角:scope 裁剪

python 复制代码
selected_sections = resolve_sections(all_sections, scope_section_ids)
scoped_content = build_interleaved_content(blocks, selected_sections, vision_text_by_index)
scoped_content, _ = truncate_scope_text(scoped_content)  # 上限约 48000 字
scope_est = estimate_scope(scoped_content, image_count)
if scope_est["level"] == "block":
    raise HTTPException(status_code=400, detail=scope_est["message"] + ";请减少勾选的章节后重试")

产品含义:用户勾选 1~2 章试跑 = 只把选中段落送进 LLM,Token 可控。


五、Token 预估:ok / warn / block

estimate_scopecore/requirement_document.py)粗算输入 Token:

python 复制代码
est_tokens = int(chars / 1.6) + image_count * 600
# warn  ≥ 12_000 tokens → level "warn"
# block ≥ 28_000 tokens → level "block",禁止同步生成
level 含义 建议
ok 可一次生成 直接点生成
warn 章节偏多 缩小范围或降低目标条数
block 接近上限 减少勾选章节,或走 异步分批 Job

大批量时创建 AiRequirementGenerateJob ,前端轮询 status/progress;任务可取消,比 AI大模型 粘贴「整份 Word 超时重来」可运维得多。


六、Prompt 工程:LLM 输出什么

场景模板 requirement_doc_to_casescore/ai_prompts.py)对输出做了硬约束,核心包括:

6.1 语义槽位(LLM 输出),禁止直接拼标题

json 复制代码
{
  "main_module": "订单",
  "sub_module": "创建",
  "feature_point": "提交订单",
  "case_description": "正常提交成功",
  "precondition": "环境:测试站可访问\n角色:已登录\n数据:购物车已有商品",
  "steps": [
    {"step": "点击\"提交订单\"按钮", "expect": "Toast 显示\"下单成功\""}
  ],
  "priority": "2",
  "test_design": "正向流程",
  "type": "功能测试"
}

Prompt 明确要求:

  • 禁止 输出 title 字段;禁止 自行拼接 【#...】 完整标题
  • 禁止 空洞表述:「执行操作」「符合预期」「功能正常」
  • steps 须一步一 expect;交互流程通常 2~4 步,只读展示可 1 步
  • grounding :文件大小、配额、错误提示等 必须与 PRD 一致,未写明则标「(需求待确认)」
  • 图-N 时:至少约 30% 用例应引用图内的 ui_elements / exact_messages

6.2 测试设计维度配比(写入 test_design,不是 type)

test_design 建议占比
正向流程 35%~45%
异常/反向 30%~40%
边界值 15%~25%
接口校验 范围内出现 API 描述时

type 走禅道「用例类型」枚举(功能测试、接口测试等),与 test_design 分离,避免把「正向/异常」写进 type 字段。


七、标题 Jinja2 + 禅道字段:平台注入

7.1 标题组装(入库前)

项目级模板(core/case_naming.py),默认示例:

text 复制代码
【#{{ story_no }}_{{ main_module }}_{{ sub_module }}】({{ feature_point }}){{ case_description }}

LLM 只填槽位 → Jinja2Template.render(**slots)_clean_rendered_title。换项目规范 只改模板,不重训模型。

7.2 禅道字段:不进 Prompt

字段 来源
product 项目「禅道绑定」
module(路径) 项目绑定 + 需求级 export_defaults 覆盖
related_story 绑定配置
stage 按 priority 映射冒烟/系统阶段(resolve_stage
python 复制代码
# zentao_bindings.py --- merge_bindings
# 需求级非空字段覆盖项目级
for key in ("product", "module", "related_story", ...):
    if req.get(key):
        merged[key] = req[key]

LLM 只写步骤、预期、前置条件 ;导出 XLSX 时 apply_bindings_to_case_fields 写入禅道列,导入失败率显著下降。


八、全量生成 vs 补充生成

模式 参数 行为
全量/替换 replace_existing=true 清空旧草稿再生成(慎用)
默认追加 replace_existing=false 新批次追加,不删旧用例
补充生成 supplement_batch_name 带已有用例摘要进 Prompt 去重,专补缺口章节

补充生成时 Prompt 会带上同批次已有用例摘要,减少 feature_point 重复;仍须人工删明显幻觉行。

批次名 batch_name 写入 source_ref=batch:名称,便于按章节筛选「哪次生成」的用例。


九、实操步骤(10 步 + 审查清单)

9.1 操作步骤

  1. AI 测试 → 需求测试中心,新建需求
  2. 上传 PRD(PDF / Word / TXT / Markdown)
  3. 等待解析,检查 章节树 与目录是否一致
  4. 项目配置 :禅道绑定、用例 标题模板(可先预览一条)
  5. 勾选本次 scope 章节 (大文档先 1~2 章 + estimate-scope 看 ok/warn)
  6. 场景绑定 :Vision(有图必填)+ requirement_case 文本模型
  7. 设置目标条数(通常 10~20/批),点击生成
  8. 表格审查:步骤是否 有具体对象+动作 ,预期是否 可判定
  9. 未覆盖章节 → 补充生成(勿一次 block 硬跑全文)
  10. 导出禅道 XLSX → 禅道导入验证

9.2 人工审查清单(导出前必过)

检查项 不合格示例
前置条件三段式 只有「已登录」无环境/数据
每步有 expect step 写 3 步,expect 只有一句
数值与 PRD 一致 编造「最多 999 条」但 PRD 写 100
图内规则已覆盖 流程图有「超限提示」但无用例
标题无重复 feature_point 同批 5 条「正常提交成功」
优先级合理 全 P1 或全 P4

原则 :AI 出 80% 草稿 ,测试负责人对 业务规则与边界 做最终签字。


十、常见失败排错

现象 原因 处理
生成按钮灰 / block scope Token ≥ 28k 预估 减章节;异步分批 Job
warn 仍要跑 12k~28k count 或再缩 scope
400 请选择 Vision 范围内有图未选 Vision 配置 平台配置 → 场景绑定
章节树空/乱 PDF 解析差 换 Word/MD;reparse-document
禅道导入字段错 未配绑定 项目 + 需求级 export_defaults
标题重复/不规范 模板未配或 LLM 槽位撞车 改 Jinja2;补充生成带去重
步骤空洞 模型弱或 scope 太短 换更强文本模型;加 extra_instructions
图内规则仍漏 Vision 弱或图模糊 换 Vision;关键图手工补 2~3 条

十一、给测开 / 后端:落地要点

要点 说明
原文件与结构分离 MinIO 存 PRD,DB 存 document_structure JSON
scope 是一等公民 所有生成 API 带 scope_section_ids
双模型边界清晰 Vision 只产文字描述,文本 LLM 不读二进制
元数据不进 Prompt 禅道 product/module/story 绑定注入
标题与内容解耦 Jinja2 + 槽位,Prompt 禁止 output title
任务化 AiRequirementGenerateJob 支持取消、进度、分批
权限隔离 需求按 project_id,避免跨项目 PRD 泄露

十二、小结

  1. Vision + 文本 双模型,解决 PRD 图文混排 漏读。
  2. 章节 scope + estimate_scope 控制 Token,block 时 分批 Job 而非硬塞。
  3. Prompt grounding 约束步骤/预期质量;平台管标题与禅道字段
  4. 补充生成 补缺口,全量替换慎用。
  5. 导出前走 审查清单 ,AI 是辅助,业务准确性人把关

附录 A:源码文件索引

顺序 文件 关注点
1 routers/ai/requirements.py 上传、generate-cases、导出、Job
2 routers/ai/test_analysis.py _build_scoped_content、测试点/方案
3 core/requirement_document.py estimate_scope、章节解析
4 core/ai_prompts.py requirement_doc_to_cases 模板
5 core/case_naming.py Jinja2 标题、render_case_title
6 core/zentao_bindings.py 绑定合并、resolve_stage
7 core/zentao_case_export.py 禅道 XLSX 导出

支持与交流